中介者模式(Mediator Pattern)是一种行为设计模式,它通过引入一个中介者对象,封装一系列对象之间的交互,使对象之间不再直接通信,而是通过中介者进行间接通信,从而降低对象间的耦合度。
中介者模式的核心角色
- Mediator(中介者):定义同事对象交互的接口
- ConcreteMediator(具体中介者):实现中介者接口,协调各同事对象的交互
- Colleague(同事):定义与其他同事交互的接口
- ConcreteColleague(具体同事):实现同事接口,通过中介者与其他同事通信
C++实现示例
下面以聊天室为例实现中介者模式,聊天室(中介者)协调多个用户(同事)之间的消息传递:
#include <iostream>
#include <string>
#include <vector>
// 前向声明
class Mediator;
// 同事类:用户
class Colleague {
protected:
Mediator* mediator;
std::string name;
public:
Colleague(Mediator* med, const std::string& n) : mediator(med), name(n) {}
virtual ~Colleague() = default;
const std::string& getName() const { return name; }
// 发送消息
virtual void send(const std::string& message) = 0;
// 接收消息
virtual void receive(const std::string& from, const std::string& message) {
std::cout << from << " 给 " << name << " 的消息: " << message << std::endl;
}
};
// 中介者接口
class Mediator {
public:
virtual ~Mediator() = default;
virtual void addColleague(Colleague* colleague) = 0;
virtual void sendMessage(Colleague* sender, const std::string& message) = 0;
virtual void sendMessageTo(Colleague* sender, Colleague* receiver, const std::string& message) = 0;
};
// 具体中介者:聊天室
class ChatRoom : public Mediator {
private:
std::vector<Colleague*> colleagues;
public:
void addColleague(Colleague* colleague) override {
colleagues.push_back(colleague);
}
// 群发消息
void sendMessage(Colleague* sender, const std::string& message) override {
for (auto colleague : colleagues) {
// 不发送给自己
if (colleague != sender) {
colleague->receive(sender->getName(), message);
}
}
}
// 私聊消息
void sendMessageTo(Colleague* sender, Colleague* receiver, const std::string& message) override {
if (receiver) {
receiver->receive(sender->getName(), message);
}
}
};
// 具体同事:聊天室用户
class ChatUser : public Colleague {
public:
ChatUser(Mediator* med, const std::string& n) : Colleague(med, n) {}
void send(const std::string& message) override {
std::cout << name << " 发送了群消息: " << message << std::endl;
mediator->sendMessage(this, message);
}
void sendTo(Colleague* receiver, const std::string& message) {
std::cout << name << " 给 " << receiver->getName() << " 发私聊: " << message << std::endl;
mediator->sendMessageTo(this, receiver, message);
}
};
int main() {
// 创建中介者(聊天室)
Mediator* chatRoom = new ChatRoom();
// 创建同事(用户)
Colleague* alice = new ChatUser(chatRoom, "Alice");
Colleague* bob = new ChatUser(chatRoom, "Bob");
Colleague* charlie = new ChatUser(chatRoom, "Charlie");
// 将用户加入聊天室
chatRoom->addColleague(alice);
chatRoom->addColleague(bob);
chatRoom->addColleague(charlie);
// 发送消息
alice->send("大家好,我是Alice!");
std::cout << "------------------------" << std::endl;
bob->send("欢迎加入!");
std::cout << "------------------------" << std::endl;
// 私聊
dynamic_cast<ChatUser*>(charlie)->sendTo(alice, "Alice,很高兴认识你");
std::cout << "------------------------" << std::endl;
dynamic_cast<ChatUser*>(bob)->sendTo(charlie, "Charlie,我们等下讨论项目");
// 清理资源
delete alice;
delete bob;
delete charlie;
delete chatRoom;
return 0;
}
代码解析
-
Colleague类:定义了用户的基本行为,包含发送和接收消息的接口,持有中介者的引用。
-
Mediator接口:定义了中介者的核心功能,包括添加同事和转发消息的方法。
-
ChatRoom类:具体的中介者实现,维护所有用户的列表,负责将消息转发给相应的用户(群发或私聊)。
-
ChatUser类:具体的同事实现,通过中介者发送消息,支持群聊和私聊功能。
中介者模式的优缺点
优点:
- 减少对象间的直接耦合,降低系统复杂度
- 将对象间的交互集中管理,便于维护和扩展
- 简化对象的设计和实现
缺点:
- 中介者可能会变得复杂,承担过多责任(成为"上帝对象")
- 当同事数量增加时,中介者的逻辑可能变得复杂
适用场景
- 系统中对象之间存在复杂的引用关系,导致依赖关系混乱
- 想通过一个中间类来封装多个类的行为,而又不想生成太多子类
- 需要创建一个运行于多个类之间的对象,又不想生成太多子类
例如:聊天室、GUI中的窗口管理器、航空管制系统、电商平台的订单处理系统等。