中介者模式(Mediator):同事不互认,都找中介者
更新时间:2026-08-25。本文按"先看不用模式的困境 → 再用模式重构 → 类图对比分析"的结构,论述中介者模式。可运行代码:demos/design-patterns/mediator。
一、问题场景:多个对象互相依赖,形成网状
对话框控件(输入框↔按钮↔列表↔状态栏互相联动)、航班调度(飞机↔塔台)、聊天室(用户↔用户)。对象之间的交互规则复杂且集中,直接互相持有会织成一张网。
二、不使用模式:同事对象互相持有,网状耦合
cpp
class ChatUser {
std::vector<ChatUser*> friends_; // 每个用户持有所有其他用户
void send(const std::string& msg) {
for (auto* f : friends_) f->recv(msg); // 加人 = 改所有成员列表
}
};
// 用户之间两两持有 → N 个对象 N×(N-1) 条边| 缺陷 | 说明 |
|---|---|
| 网状耦合 | N 个对象两两相连,边数 O(N²) |
| 违反 SRP | 每个对象既干自己的事又管跟所有人的协调 |
| 交互规则散落 | 联动逻辑分散在各对象里,改规则要改多处 |
| 加成员成本高 | 新对象要认识所有旧对象 |
不使用模式的类图

三、使用模式:中介者统一协调,星状耦合
中介者模式把所有交互规则收敛到一个中介者对象;同事对象只认识中介者,互相不持有。交互时发消息给中介者,由中介者决定转发给谁——边数从 O(N²) 降到 O(N)。
cpp
// chat_mediator.h
class ChatMediator; // 前向声明
class ChatUser { // 同事
public:
explicit ChatUser(ChatMediator& m) : mediator_(m) {}
void send(const std::string& msg);
void recv(const std::string& from, const std::string& msg);
private:
ChatMediator& mediator_; // 只认识中介者
std::string name_;
};
class ChatMediator { // 中介者:协调所有同事
public:
void addUser(ChatUser* u) { users_.push_back(u); }
void broadcast(const std::string& from, const std::string& msg) {
for (auto* u : users_) if (u != /*from*/) u->recv(from, msg);
}
private:
std::vector<ChatUser*> users_;
};
void ChatUser::send(const std::string& msg) { mediator_.broadcast(name_, msg); }
// 加人 = mediator.addUser,用户之间互不认识使用模式的类图

四、类图对比与分析
| 维度 | 不使用(网状) | 使用中介者 |
|---|---|---|
| 边数 | O(N²) | O(N) |
| 交互规则 | 散落各对象 | 集中中介者一处 |
| 加成员 | 认识所有人 | 只注册到中介者 |
| 对象职责 | 干自己的 + 协调所有人 | 只干自己的(SRP) |
| 单点风险 | 无 | 中介者变"上帝对象",规则多了它膨胀 |
分析结论:中介者把"交互规则"从 N 个对象抽到 1 个对象——复杂度从分散到集中。代价是中介者可能膨胀为"上帝对象"(所有规则挤一处)、性能上每次交互多一次中介转发。它是"把复杂系统变简单"与"制造新的复杂中心"的权衡。
五、适用边界
| 适用 | 不适用 |
|---|---|
| 对象间交互规则复杂且集中 | 交互规则简单(直接持有即可) |
| 对象数多、网状耦合严重 | 对象间是单向依赖(不需要中介) |
| 交互规则预期会频繁调整 | 中介者膨胀不可控(考虑拆分为多个中介者) |
与外观的区别:外观封装"子系统对外提供的服务"(单向,给客户端看);中介者协调"对象之间的交互"(双向,对象互相转发)。与观察者的区别:观察者是"一对多广播"(主题通知订阅者);中介者是"多对多协调"(所有同事经中介转发)。
一句话总结
中介者模式把交互规则收敛到中介者,同事对象只认识中介者、互不持有——耦合从 O(N²) 网状降到 O(N) 星状;交互规则集中一处、加成员成本低;代价是中介者可能膨胀为"上帝对象",规则复杂时需拆分中介者控制复杂度。