Bootstrap

设计模式——中介者模式

定义

中介者模式(Mediator Pattern)是一种行为设计模式。它通过引入一个中介者对象来封装一系列对象之间的交互,使得这些对象之间不再直接相互引用,而是通过中介者来进行通信。这样可以降低对象之间的耦合度,使得系统的结构更加清晰,易于维护和扩展。

UML 类图及主要角色

  • 抽象中介者(Mediator):
    定义了一个接口,用于与各同事(Colleague)对象进行通信。在 C++ 中,通常是一个抽象类,包含抽象的通知方法,用于接收同事对象发送的消息并进行处理。
  • 具体中介者(Concrete Mediator):
    实现了抽象中介者中的接口,它了解并维护各个同事对象的引用,负责协调各个同事对象之间的交互。当收到一个同事对象的消息时,它会根据业务逻辑决定将消息转发给哪些其他同事对象。
  • 抽象同事(Colleague):
    定义了同事类的接口,每个同事对象都知道它的中介者对象,并且在需要与其他同事对象通信时,通过中介者对象来发送消息。
  • 具体同事(Concrete Colleague):
    实现了抽象同事类的接口,具体同事对象包含自身的业务逻辑,并通过中介者对象来和其他同事对象进行通信。例如,在一个聊天系统中,每个用户(具体同事)可以通过聊天服务器(具体中介者)来发送和接收消息,而不是直接与其他用户通信。

简单示例:简单的聊天系统

抽象中介者类

class ChatMediator {
public:
  virtual void sendMessage(const std::string& msg, class ChatUser* user) = 0;
};

具体中介者类

class ChatRoom : public ChatMediator {
private:
  std::vector<ChatUser*> users;
public:
  void addUser(ChatUser* user) {
    users.push_back(user);
  }
  void sendMessage(const std::string& msg, ChatUser* user) override {
    for (ChatUser* u : users) {
      if (u!= user) {
        u->receive(msg);
      }
    }
  }
};

抽象同事类

class ChatUser {
protected:
  ChatMediator* mediator;
public:
  ChatUser(ChatMediator* med) : mediator(med) {}
  virtual void send(const std::string& msg) = 0;
  virtual void receive(const std::string& msg) = 0;
};

具体同事类

class ChatUserImpl : public ChatUser {
private:
  std::string name;
public:
  ChatUserImpl(ChatMediator* med, const std::string& n) : ChatUser(med), name(n) {}
  void send(const std::string& msg) override {
    mediator->sendMessage(msg, this);
  }
  void receive(const std::string& msg) override {
    std::cout << name << " received message: " << msg << std::endl;
  }
};

使用示例

int main() {
  ChatRoom room;
  ChatUser* user1 = new ChatUserImpl(&room, "User1");
  ChatUser* user2 = new ChatUserImpl(&room, "User2");
  room.addUser(user1);
  room.addUser(user2);
  user1->send("Hello!");
  delete user1;
  delete user2;
  return 0;
}

在这个示例中,ChatMediator是抽象中介者,ChatRoom是具体中介者,负责管理用户并转发消息。ChatUser是抽象同事,ChatUserImpl是具体同事,用户通过中介者(聊天房间)来发送和接收消息。

优点

  • 降低耦合度:
    减少了同事对象之间的直接依赖,使得各个同事对象可以独立地变化和扩展,而不会影响到其他同事对象。例如在复杂的软件系统中,不同模块之间的通信通过中介者进行,模块内部的修改不会直接影响其他模块。
  • 集中控制交互逻辑:
    中介者对象可以集中管理和协调同事对象之间的交互,使得交互逻辑更加清晰。比如在游戏开发中,游戏场景中的各个游戏对象之间的交互(如碰撞检测、触发事件等)可以通过一个场景中介者来统一管理。

缺点

  • 中介者可能会变得复杂:
    如果同事对象之间的交互过于复杂,中介者对象可能会包含大量的逻辑来协调这些交互,导致中介者类变得庞大和复杂,难以维护。
  • 系统的可扩展性可能会受到限制:
    当需要添加新的同事对象或者新的交互方式时,可能需要修改中介者类的代码,这可能会对系统的扩展性产生一定的影响。不过,通过合理的设计和接口规划,可以在一定程度上减轻这种影响。

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;