中介者设计模式属于行为型设计模式的一种,它的核心作用是降低多个对象之间的耦合度,让对象之间的交互通过中介者统一处理,避免对象之间直接引用导致的依赖混乱。在实际的C++项目开发中,当多个业务模块需要频繁通信时,直接让模块之间互相调用会让系统结构变得复杂,后续修改和扩展都会变得困难,使用中介者模式可以有效解决这个问题。

中介者设计模式的核心角色
中介者模式主要包含以下几个核心角色:
- 中介者接口:定义各个模块与中介者交互的接口,声明处理模块通信的方法
- 具体中介者:实现中介者接口,维护各个模块的引用,协调各个模块之间的交互逻辑
- 同事类接口:定义各个业务模块的基础接口,声明模块向中介者发送消息、接收中介者消息的方法
- 具体同事类:实现同事类接口,每个具体同事类只知道自己的业务逻辑,不知道其他同事类的存在,所有通信都通过中介者完成
场景示例说明
我们用一个简单的聊天室场景来演示中介者模式的实现,聊天室中有多个用户,用户之间发送消息不是直接一对一发送,而是通过聊天室这个中介者转发,所有用户只需要和聊天室交互即可,不需要知道其他用户的具体信息。
C++实现完整源码
1. 定义中介者接口和同事类接口
#include <iostream>
#include <string>
#include <vector>
#include <memory>
// 前向声明同事类
class Colleague;
// 中介者接口
class Mediator {
public:
virtual ~Mediator() = default;
// 注册同事对象到中介者
virtual void registerColleague(Colleague* colleague) = 0;
// 转发消息,from是发送者,msg是消息内容
virtual void relayMessage(Colleague* from, const std::string& msg) = 0;
};
// 同事类接口
class Colleague {
protected:
Mediator* mediator; // 持有中介者引用
std::string name; // 同事名称
public:
Colleague(Mediator* med, const std::string& n) : mediator(med), name(n) {}
virtual ~Colleague() = default;
// 向中介者发送消息
virtual void sendMessage(const std::string& msg) = 0;
// 接收来自中介者的消息
virtual void receiveMessage(Colleague* from, const std::string& msg) = 0;
// 获取同事名称
std::string getName() const { return name; }
};
2. 实现具体中介者和具体同事类
// 具体中介者:聊天室
class ChatRoomMediator : public Mediator {
private:
std::vector<Colleague*> colleagues; // 维护所有注册的同事对象
public:
void registerColleague(Colleague* colleague) override {
colleagues.push_back(colleague);
}
void relayMessage(Colleague* from, const std::string& msg) override {
// 遍历所有同事,除了发送者自己,都转发消息
for (Colleague* colleague : colleagues) {
if (colleague != from) {
colleague->receiveMessage(from, msg);
}
}
}
};
// 具体同事类:聊天用户
class ChatUser : public Colleague {
public:
ChatUser(Mediator* med, const std::string& n) : Colleague(med, n) {
// 创建用户时自动注册到中介者
med->registerColleague(this);
}
void sendMessage(const std::string& msg) override {
std::cout << name << " 发送消息:" << msg << std::endl;
// 调用中介者转发消息
mediator->relayMessage(this, msg);
}
void receiveMessage(Colleague* from, const std::string& msg) override {
std::cout << name << " 收到来自 " << from->getName() << " 的消息:" << msg << std::endl;
}
};
3. 测试代码
int main() {
// 创建聊天室中介者
ChatRoomMediator chatRoom;
// 创建三个聊天用户,自动注册到聊天室
ChatUser user1(&chatRoom, "用户A");
ChatUser user2(&chatRoom, "用户B");
ChatUser user3(&chatRoom, "用户C");
// 用户1发送消息
user1.sendMessage("大家好,我是用户A");
std::cout << "------------------------" << std::endl;
// 用户2发送消息
user2.sendMessage("你好呀,用户A");
return 0;
}
代码运行结果说明
编译运行上述代码后,输出结果如下:
用户A 发送消息:大家好,我是用户A 用户B 收到来自 用户A 的消息:大家好,我是用户A 用户C 收到来自 用户A 的消息:大家好,我是用户A ------------------------ 用户B 发送消息:你好呀,用户A 用户A 收到来自 用户B 的消息:你好呀,用户A 用户C 收到来自 用户B 的消息:你好呀,用户A
可以看到,用户之间没有直接调用对方的发送或接收方法,所有消息都通过ChatRoomMediator这个中介者转发,如果用户后续需要新增其他用户,只需要创建新的ChatUser对象即可,不需要修改已有用户类的代码,符合开闭原则,有效降低了模块之间的耦合度。
中介者模式的适用场景
- 系统中存在多个对象,且这些对象之间存在复杂的网状引用关系,导致依赖混乱时
- 想要复用某个类,但是该类依赖过多其他类,难以单独复用的情况
- 多个模块需要频繁交互通信,且交互逻辑可能会频繁变化的场景
注意事项
虽然中介者模式可以降低耦合度,但如果系统中所有模块的交互都通过一个中介者处理,会导致中介者的逻辑变得非常复杂,成为一个庞大的类,反而提升维护难度。因此在实际使用中,需要根据业务场景合理拆分中介者,避免中介者过度膨胀。