一、中介者模式核心概念解析
中介者模式是一种行为型设计模式 ,它的核心作用是:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。
你可以把它理解成生活中的「项目经理」:一个项目里有设计师、开发、测试多个角色,如果没有项目经理(中介者),每个人都要直接沟通(设计师找开发、开发找测试、测试找设计师),耦合度极高;有了项目经理后,所有人只需要和项目经理沟通,由项目经理统一协调,大大降低了角色间的直接依赖。
中介者模式的关键角色
- 抽象中介者(Mediator):定义中介者与同事对象之间交互的接口,通常包含注册同事对象、转发交互请求的方法。
- 具体中介者(ConcreteMediator):实现抽象中介者接口,持有所有同事对象的引用,负责具体的协调逻辑,处理同事对象的请求并转发给相关对象。
- 抽象同事类(Colleague):定义同事对象的通用接口,持有抽象中介者的引用,所有具体同事类都继承此类。
- 具体同事类(ConcreteColleague):实现抽象同事类接口,当需要与其他同事交互时,不直接调用其他同事,而是通过中介者转发请求。
中介者模式的核心优势
- 降低对象间的耦合度:同事对象无需知道其他同事的具体实现,只依赖中介者。
- 集中管理交互逻辑:所有对象间的交互都集中在中介者中,便于统一维护和扩展。
- 符合「迪米特法则」(最少知道原则):每个对象只需要和中介者通信,减少不必要的依赖。
二、C++ 代码示例(聊天室场景)
下面以「多人聊天室」为例:聊天室里有多个用户(具体同事),用户发送消息时不直接发给其他用户,而是通过聊天室(具体中介者)转发给所有在线用户,这是中介者模式的典型应用。
完整代码
cpp
运行
cpp
#include <iostream>
#include <string>
#include <vector>
#include <memory> // 智能指针,避免内存泄漏
// 前置声明:抽象同事类(用户),供抽象中介者使用
class Colleague;
// 1. 抽象中介者:定义聊天室的通用接口
class Mediator {
public:
virtual ~Mediator() = default;
// 注册用户到聊天室
virtual void registerColleague(std::shared_ptr<Colleague> colleague) = 0;
// 转发消息:由发送者发送,中介者转发给其他用户
virtual void sendMessage(const std::string& message, std::shared_ptr<Colleague> sender) = 0;
};
// 2. 抽象同事类:定义用户的通用接口
class Colleague {
protected:
std::shared_ptr<Mediator> mediator_; // 持有中介者引用
std::string name_; // 用户名
public:
Colleague(std::shared_ptr<Mediator> mediator, const std::string& name)
: mediator_(mediator), name_(name) {}
virtual ~Colleague() = default;
// 获取用户名
std::string getName() const { return name_; }
// 发送消息(通过中介者)
virtual void send(const std::string& message) = 0;
// 接收消息(由中介者调用)
virtual void receive(const std::string& message, const std::string& senderName) = 0;
};
// 3. 具体中介者:聊天室
class ChatRoomMediator : public Mediator {
private:
std::vector<std::shared_ptr<Colleague>> colleagues_; // 存储所有在线用户
public:
// 注册用户
void registerColleague(std::shared_ptr<Colleague> colleague) override {
colleagues_.push_back(colleague);
std::cout << "【聊天室】用户 " << colleague->getName() << " 加入聊天室" << std::endl;
}
// 转发消息:给除发送者外的所有用户发消息
void sendMessage(const std::string& message, std::shared_ptr<Colleague> sender) override {
for (auto& colleague : colleagues_) {
// 排除发送者自己
if (colleague != sender) {
colleague->receive(message, sender->getName());
}
}
}
};
// 4. 具体同事类:普通用户
class User : public Colleague {
public:
User(std::shared_ptr<Mediator> mediator, const std::string& name)
: Colleague(mediator, name) {}
// 发送消息:调用中介者的转发方法
void send(const std::string& message) override {
std::cout << "【" << name_ << "】发送消息:" << message << std::endl;
mediator_->sendMessage(message, shared_from_this()); // 转发给中介者
}
// 接收消息:显示收到的消息
void receive(const std::string& message, const std::string& senderName) override {
std::cout << "【" << name_ << "】收到来自" << senderName << "的消息:" << message << std::endl;
}
};
// 客户端代码
int main() {
// 1. 创建聊天室(具体中介者)
std::shared_ptr<Mediator> chatRoom = std::make_shared<ChatRoomMediator>();
// 2. 创建用户(具体同事),并注册到聊天室
std::shared_ptr<Colleague> user1 = std::make_shared<User>(chatRoom, "张三");
std::shared_ptr<Colleague> user2 = std::make_shared<User>(chatRoom, "李四");
std::shared_ptr<Colleague> user3 = std::make_shared<User>(chatRoom, "王五");
chatRoom->registerColleague(user1);
chatRoom->registerColleague(user2);
chatRoom->registerColleague(user3);
// 3. 用户发送消息(通过中介者转发)
std::cout << "\n===== 聊天开始 =====" << std::endl;
user1->send("大家好,我是张三!");
std::cout << "---------------------" << std::endl;
user2->send("张三你好,我是李四~");
std::cout << "---------------------" << std::endl;
user3->send("大家好,新人报道👋");
return 0;
}
代码解释
- 抽象中介者(Mediator) :定义了
registerColleague(注册用户)和sendMessage(转发消息)两个核心接口,是聊天室的通用规范。 - 具体中介者(ChatRoomMediator) :
- 持有所有在线用户的列表(
colleagues_); - 实现
registerColleague:将用户加入聊天室; - 实现
sendMessage:遍历所有用户,把消息转发给除发送者外的其他用户(核心协调逻辑)。
- 持有所有在线用户的列表(
- 抽象同事类(Colleague) :
- 持有中介者的引用(
mediator_),确保所有用户都能访问聊天室; - 定义
send(发送消息)和receive(接收消息)的接口,统一用户行为。
- 持有中介者的引用(
- 具体同事类(User) :
- 实现
send方法:用户发送消息时,不直接调用其他用户,而是通过mediator_->sendMessage把消息交给中介者转发; - 实现
receive方法:接收中介者转发的消息,并打印显示。
- 实现
- 客户端代码 :
- 创建聊天室和用户,将用户注册到聊天室;
- 调用用户的
send方法发送消息,所有交互由中介者协调,用户间无直接依赖。
运行结果
plaintext
cpp
【聊天室】用户 张三 加入聊天室
【聊天室】用户 李四 加入聊天室
【聊天室】用户 王五 加入聊天室
===== 聊天开始 =====
【张三】发送消息:大家好,我是张三!
【李四】收到来自张三的消息:大家好,我是张三!
【王五】收到来自张三的消息:大家好,我是张三!
---------------------
【李四】发送消息:张三你好,我是李四~
【张三】收到来自李四的消息:张三你好,我是李四~
【王五】收到来自李四的消息:张三你好,我是李四~
---------------------
【王五】发送消息:大家好,新人报道👋
【张三】收到来自王五的消息:大家好,新人报道👋
【李四】收到来自王五的消息:大家好,新人报道👋
三、中介者模式的扩展思考(进阶补充)
1. 中介者模式的潜在问题
- 中介者可能会「过度膨胀」:所有交互逻辑都集中在中介者中,当交互场景复杂时(比如聊天室支持私聊、禁言等),具体中介者类会变得非常庞大,难以维护。
- 中介者成为「单点故障」:如果中介者出错,整个系统的交互都会受影响。
2. 优化方向
- 拆分中介者:将复杂的交互逻辑拆分为多个细分中介者(比如私聊中介者、群聊中介者);
- 结合其他模式:比如用工厂模式创建中介者,用观察者模式优化中介者与同事的消息通知。
总结
- 核心作用:中介者模式通过引入统一的中介对象,封装多个对象间的交互,降低对象间的直接耦合,让交互逻辑集中管理。
- 核心结构:抽象中介者(定义接口)→ 具体中介者(实现协调逻辑);抽象同事(持有中介者)→ 具体同事(通过中介者交互)。
- 适用场景:多个对象间存在复杂的交互关系(如聊天室、GUI 组件交互、分布式系统协调),且希望降低对象间耦合时。
这个模式的核心思想是「化繁为简」------ 把多对多的复杂交互,转化为同事与中介者之间的一对多交互,是解耦复杂系统的重要手段。