中介者模式(Mediator Pattern)是一种行为型设计模式,它通过引入一个中介者对象来封装一系列对象之间的交互,使这些对象不需要显式地相互引用,从而降低它们之间的耦合度。中介者负责协调各对象之间的通信,使得对象之间的关系更加简单。

中介者模式的核心角色

  1. 中介者(Mediator):定义一个接口,用于与各同事对象通信
  2. 具体中介者(Concrete Mediator):实现中介者接口,协调各同事对象的交互,了解并维护各个同事
  3. 同事(Colleague):定义与其他同事通信的接口,每个同事都知道中介者对象
  4. 具体同事(Concrete Colleague):实现同事接口,当需要与其他同事通信时,通过中介者进行

中介者模式的实现示例

下面以"聊天室系统"为例展示中介者模式的实现,聊天室(中介者)负责协调多个用户(同事)之间的消息传递,用户不需要直接相互引用:

#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>

// 前向声明
class User;

// 中介者接口
class Mediator {
public:
    virtual void registerUser(User* user) = 0;
    virtual void sendMessage(const std::string& message, User* sender) = 0;
    virtual void sendPrivateMessage(const std::string& message, User* sender, const std::string& receiverName) = 0;
    virtual ~Mediator() = default;
};

// 同事接口:用户
class User {
protected:
    Mediator* mediator;
    std::string name;

public:
    User(Mediator* med, const std::string& userName) 
        : mediator(med), name(userName) {}

    std::string getName() const {
        return name;
    }

    virtual void send(const std::string& message) {
        std::cout << name << " 发送消息: " << message << std::endl;
        mediator->sendMessage(message, this);
    }

    virtual void sendPrivate(const std::string& message, const std::string& receiverName) {
        std::cout << name << " 向 " << receiverName << " 发送私聊: " << message << std::endl;
        mediator->sendPrivateMessage(message, this, receiverName);
    }

    virtual void receive(const std::string& message, const std::string& senderName) {
        std::cout << name << " 收到来自 " << senderName << " 的消息: " << message << std::endl;
    }

    virtual ~User() = default;
};

// 具体中介者:聊天室
class ChatRoom : public Mediator {
private:
    std::unordered_map<std::string, User*> users;  // 存储用户列表

public:
    void registerUser(User* user) override {
        users[user->getName()] = user;
        std::cout << user->getName() << " 加入聊天室" << std::endl;
    }

    // 群发消息
    void sendMessage(const std::string& message, User* sender) override {
        for (const auto& pair : users) {
            // 不发送给自己
            if (pair.second != sender) {
                pair.second->receive(message, sender->getName());
            }
        }
    }

    // 私聊消息
    void sendPrivateMessage(const std::string& message, User* sender, const std::string& receiverName) override {
        auto it = users.find(receiverName);
        if (it != users.end()) {
            it->second->receive(message, sender->getName());
        } else {
            std::cout << "错误: 用户 " << receiverName << " 不在聊天室中" << std::endl;
        }
    }
};

// 具体同事:普通用户
class RegularUser : public User {
public:
    RegularUser(Mediator* med, const std::string& name) : User(med, name) {}
};

// 客户端使用
int main() {
    // 创建中介者:聊天室
    Mediator* chatRoom = new ChatRoom();

    // 创建用户并加入聊天室
    User* alice = new RegularUser(chatRoom, "Alice");
    User* bob = new RegularUser(chatRoom, "Bob");
    User* charlie = new RegularUser(chatRoom, "Charlie");

    chatRoom->registerUser(alice);
    chatRoom->registerUser(bob);
    chatRoom->registerUser(charlie);

    // 发送消息
    std::cout << std::endl;
    alice->send("大家好!我是Alice");
    
    std::cout << std::endl;
    bob->send("欢迎加入!");
    
    std::cout << std::endl;
    alice->sendPrivate("Bob,你好!", "Bob");
    
    std::cout << std::endl;
    charlie->sendPrivate("Alice,很高兴认识你", "Alice");

    // 清理资源
    delete charlie;
    delete bob;
    delete alice;
    delete chatRoom;

    return 0;
}

中介者模式的工作原理

  1. 同事对象不直接相互通信,而是通过中介者传递消息
  2. 中介者知道所有同事对象,并负责协调它们之间的交互
  3. 当一个同事需要与其他同事通信时,它将消息发送给中介者
  4. 中介者根据消息类型和发送者,决定将消息转发给哪些同事

中介者模式与外观模式的区别

  • 中介者模式:关注多个对象之间的交互,使它们解耦,各对象可以通过中介者相互通信
  • 外观模式:为子系统提供一个简化的接口,侧重于简化客户端与子系统的交互

中介者模式的应用场景

  1. 当多个对象之间存在复杂的交互关系,导致它们之间的耦合度很高时
  2. 当一个对象的行为会影响其他多个对象,且需要集中管理这些交互时
  3. 当希望通过一个中心控制点来协调系统中各部分的行为时

中介者模式的优缺点

优点

  • 减少了对象之间的直接耦合,降低了系统的复杂性
  • 将多对多的交互关系转变为一对多的关系,使系统更易于理解和维护
  • 集中管理对象之间的交互,便于修改和扩展
  • 符合迪米特原则(最少知识原则),对象只需要了解中介者

缺点

  • 中介者可能会变得非常复杂,承担过多责任,成为"上帝类"
  • 如果中介者出现问题,可能会影响整个系统
  • 增加了系统的抽象层次,可能提高理解难度

中介者模式在实际开发中应用广泛,例如GUI中的事件总线、聊天系统、MVC模式中的控制器(Controller)部分、分布式系统中的协调器等。在这些场景中,中介者模式能够有效地简化对象之间的交互,提高系统的可维护性。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐