<摘要>
中介者模式就像是软件世界中的"交通警察",它站在复杂的对象交叉路口,指挥着各个对象之间的通信流向。想象一下,如果没有交通警察,每个司机都要直接与其他所有司机协商通行顺序,那将是多么混乱的场景!中介者模式正是为了解决这种对象间复杂网状依赖关系而生的。本文将带你深入了解这个巧妙的设计模式,从它的诞生背景到现代应用,通过生动的现实案例(包括空中交通管制、聊天室系统等)展示其强大威力。我们还会亲手实现完整的中介者系统,用直观的图表揭示其工作原理。
<解析>
中介者模式深度解析:软件架构的"交通指挥官"
1. 背景与核心概念
1.1 起源与发展历程
让我们从一个生动的比喻开始:想象一个繁忙的机场控制塔。如果没有控制塔,每架飞机都需要直接与其他所有飞机通信来协调起飞、降落和航线,这将是灾难性的。中介者模式就是这个"控制塔",它诞生于解决对象间复杂通信的需求。
1994年:GoF(Gang of Four)在《设计模式:可复用面向对象软件的基础》中首次正式提出中介者模式。
2000年代:随着MVC(Model-View-Controller)架构的流行,控制器作为中介者的角色被广泛认可。
现状趋势:现代微服务架构中的API网关、消息队列、事件总线都是中介者思想的延伸。
1.2 核心概念解析
让我们用UML类图来理解中介者模式的核心结构:
<<interface>> Mediator +notify(sender: Component, event: string) void ConcreteMediator -component1: Component1 -component2: Component2 -component3: Component3 +notify(sender: Component, event: string) void BaseComponent #mediator: Mediator +setMediator(mediator: Mediator) void Component1 +doA() void +doB() void Component2 +doC() void +doD() void Component3 +doE() void +doF() void
关键角色说明:
角色 | 职责 | 现实比喻 |
---|---|---|
Mediator(中介者) | 定义组件间通信的接口 | 交通警察的指挥规范 |
ConcreteMediator(具体中介者) | 实现中介者接口,协调各组件交互 | 具体的交通警察 |
Component(组件) | 每个需要交互的对象基类 | 道路上的车辆 |
ConcreteComponent(具体组件) | 实现具体业务逻辑的组件 | 公交车、出租车、私家车 |
1.3 模式转换:从网状到星状
中介者模式最核心的价值在于架构的转变:
转换前(网状结构):
组件A 组件B 组件C 组件D
转换后(星状结构):
组件A 中介者 组件B 组件C 组件D
这种转变带来的核心优势:
方面 | 网状结构 | 星状结构 |
---|---|---|
耦合度 | 高(每个组件依赖多个其他组件) | 低(只依赖中介者) |
可维护性 | 差(修改一个组件影响多个组件) | 好(修改隔离在中介者内) |
可扩展性 | 困难(新增组件需要修改多个现有组件) | 容易(只需在中介者中注册) |
复杂度 | O(n²) 的交互关系 | O(n) 的交互关系 |
2. 设计意图与考量
2.1 核心设计目标
中介者模式的设计哲学围绕三个核心目标:解耦 、简化 、集中控制。
2.1.1 解耦组件依赖
cpp
// 不好的做法:组件间直接依赖
class ComponentA {
ComponentB* b;
ComponentC* c;
public:
void operation() {
// 需要直接调用其他组件的方法
b->doSomething();
c->doAnotherThing();
}
};
// 好的做法:通过中介者解耦
class ComponentA {
Mediator* mediator;
public:
void operation() {
// 通过中介者协调,不直接依赖其他组件
mediator->notify(this, "operation_called");
}
};
2.1.2 集中控制逻辑
所有组件间的交互逻辑都集中在中介者中,便于维护和修改:
cpp
class DialogMediator : public Mediator {
Button* okButton;
TextBox* nameTextBox;
CheckBox* agreeCheckBox;
public:
void notify(Component* sender, const string& event) override {
if (sender == okButton && event == "click") {
// 集中处理按钮点击的逻辑
if (nameTextBox->getText().empty()) {
showError("姓名不能为空");
} else if (!agreeCheckBox->isChecked()) {
showError("请同意协议");
} else {
processSubmit();
}
}
}
};
2.2 设计权衡与考量
2.2.1 上帝对象风险 vs 分散复杂度
风险:中介者可能变成"上帝对象",承担过多职责。
解决方案:使用多个专门的中介者:
cpp
// 专门处理用户交互的中介者
class UIMediator : public Mediator {
// 只处理UI组件间的交互
};
// 专门处理业务逻辑的中介者
class BusinessMediator : public Mediator {
// 只处理业务组件间的交互
};
// 专门处理数据流的中介者
class DataFlowMediator : public Mediator {
// 只处理数据组件间的交互
};
2.2.2 性能考量
中介者模式引入的间接调用可能带来性能开销,但在大多数场景下是可接受的:
cpp
// 直接调用(快但耦合度高)
componentA->directCall(componentB);
// 通过中介者(稍慢但解耦)
mediator->forwardCall(componentA, componentB);
在需要高性能的场合,可以考虑使用编译时中介者(基于模板)来减少运行时开销。
3. 实例与应用场景
3.1 案例1:聊天室系统(经典中介者模式)
应用场景:多个用户需要相互通信,但不希望直接依赖其他用户对象。
完整代码实现:
cpp
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <algorithm>
/**
* @brief 中介者接口
*
* 定义组件间通信的契约,具体的消息转发逻辑由子类实现。
* 采用抽象类而非纯接口,提供一些基础功能。
*/
class ChatMediator {
public:
virtual ~ChatMediator() = default;
/**
* @brief 发送消息的核心方法
*
* @param message 消息内容
* @param sender 发送者标识
* @param receiver 接收者标识(空字符串表示广播)
*/
virtual void sendMessage(const std::string& message,
const std::string& sender,
const std::string& receiver = "") = 0;
/**
* @brief 注册用户到聊天室
*
* @param userName 用户名
*/
virtual void registerUser(const std::string& userName) = 0;
};
// 前向声明
class User;
/**
* @brief 具体聊天室中介者
*
* 实现聊天室的具体逻辑,管理用户注册、消息路由、权限控制等。
* 充当所有用户通信的中央枢纽。
*/
class ConcreteChatMediator : public ChatMediator {
private:
std::vector<std::shared_ptr<User>> users;
std::vector<std::string> userNames;
public:
void registerUser(const std::string& userName) override {
userNames.push_back(userName);
std::cout << "用户 " << userName << " 加入聊天室" << std::endl;
}
void sendMessage(const std::string& message,
const std::string& sender,
const std::string& receiver = "") override {
std::cout << "--- 消息路由开始 ---" << std::endl;
std::cout << "发送者: " << sender << std::endl;
std::cout << "消息内容: " << message << std::endl;
if (!receiver.empty()) {
// 私聊消息
std::cout << "接收者: " << receiver << " [私聊]" << std::endl;
auto it = std::find(userNames.begin(), userNames.end(), receiver);
if (it != userNames.end()) {
std::cout << "私聊消息成功发送给 " << receiver << std::endl;
} else {
std::cout << "错误: 用户 " << receiver << " 不存在" << std::endl;
}
} else {
// 广播消息
std::cout << "接收者: 所有在线用户 [广播]" << std::endl;
for (const auto& user : userNames) {
if (user != sender) { // 不发送给自己
std::cout << " -> 发送给: " << user << std::endl;
}
}
}
std::cout << "--- 消息路由结束 ---" << std::endl;
}
};
/**
* @brief 用户基类
*
* 所有聊天用户的基类,维护对中介者的引用。
* 提供发送和接收消息的基础能力。
*/
class User {
protected:
std::shared_ptr<ChatMediator> mediator;
std::string name;
public:
User(const std::string& userName, std::shared_ptr<ChatMediator> med)
: name(userName), mediator(med) {}
virtual ~User() = default;
/**
* @brief 发送消息
*
* @param message 消息内容
* @param receiver 接收者(空表示广播)
*/
virtual void send(const std::string& message, const std::string& receiver = "") {
std::cout << name << " 尝试发送消息..." << std::endl;
mediator->sendMessage(message, name, receiver);
}
/**
* @brief 接收消息
*
* @param message 消息内容
* @param sender 发送者
*/
virtual void receive(const std::string& message, const std::string& sender) {
std::cout << name << " 收到来自 " << sender << " 的消息: " << message << std::endl;
}
std::string getName() const { return name; }
};
/**
* @brief 普通用户类
*
* 实现普通用户的具体行为,可以发送和接收消息。
*/
class BasicUser : public User {
public:
BasicUser(const std::string& name, std::shared_ptr<ChatMediator> mediator)
: User(name, mediator) {}
};
/**
* @brief 管理员用户类
*
* 具有特殊权限的用户,可以发送系统消息和踢人等功能。
*/
class AdminUser : public User {
public:
AdminUser(const std::string& name, std::shared_ptr<ChatMediator> mediator)
: User(name, mediator) {}
void sendSystemMessage(const std::string& message) {
std::cout << "[系统消息] 管理员 " << name << " 发布: " << message << std::endl;
send("[系统] " + message); // 系统消息广播
}
};
// 演示代码
int main() {
// 创建聊天室中介者
auto chatMediator = std::make_shared<ConcreteChatMediator>();
// 创建用户并注册
chatMediator->registerUser("Alice");
chatMediator->registerUser("Bob");
chatMediator->registerUser("Charlie");
chatMediator->registerUser("管理员");
// 创建用户对象
auto alice = std::make_shared<BasicUser>("Alice", chatMediator);
auto bob = std::make_shared<BasicUser>("Bob", chatMediator);
auto charlie = std::make_shared<BasicUser>("Charlie", chatMediator);
auto admin = std::make_shared<AdminUser>("管理员", chatMediator);
std::cout << "\n=== 聊天室演示开始 ===" << std::endl;
// 演示消息发送
alice->send("大家好,我是Alice!"); // 广播消息
bob->send("你好Alice!", "Alice"); // 私聊消息
admin->sendSystemMessage("欢迎新成员加入!"); // 系统消息
std::cout << "=== 聊天室演示结束 ===" << std::endl;
return 0;
}
聊天室交互时序图:
Alice 聊天中介者 Bob Charlie send("大家好", "") 广播消息 receive("大家好", "Alice") receive("大家好", "Alice") send("你好Alice", "Alice") 私聊消息 receive("你好Alice", "Bob") 只发送给Alice Alice 聊天中介者 Bob Charlie
3.2 案例2:GUI对话框系统(MVC中的控制器)
应用场景:对话框中多个控件需要复杂交互,如表单验证、状态联动等。
完整代码实现:
cpp
#include <iostream>
#include <string>
#include <memory>
#include <vector>
// 前向声明
class DialogMediator;
/**
* @brief UI组件基类
*
* 所有对话框控件的基类,维护对中介者的引用。
* 提供基本的启用/禁用状态管理。
*/
class Widget {
protected:
DialogMediator* mediator;
std::string name;
bool enabled;
public:
Widget(const std::string& widgetName, DialogMediator* med = nullptr)
: name(widgetName), mediator(med), enabled(true) {}
virtual ~Widget() = default;
void setMediator(DialogMediator* med) { mediator = med; }
void setEnabled(bool isEnabled) { enabled = isEnabled; }
bool isEnabled() const { return enabled; }
std::string getName() const { return name; }
// 抽象方法,子类实现具体行为
virtual void onChange() = 0;
virtual void draw() = 0;
};
/**
* @brief 对话框中介者接口
*
* 定义对话框组件间的交互协议。
*/
class DialogMediator {
public:
virtual ~DialogMediator() = default;
virtual void widgetChanged(Widget* widget) = 0;
virtual void addWidget(Widget* widget) = 0;
};
/**
* @brief 按钮控件
*
* 代表对话框中的按钮,可以点击触发动作。
*/
class Button : public Widget {
private:
std::string text;
public:
Button(const std::string& btnName, const std::string& btnText)
: Widget(btnName), text(btnText) {}
void onClick() {
if (enabled) {
std::cout << "按钮 '" << text << "' 被点击" << std::endl;
onChange();
}
}
void onChange() override {
if (mediator) {
mediator->widgetChanged(this);
}
}
void draw() override {
std::cout << "[按钮] " << text << " " << (enabled ? "[可用]" : "[禁用]") << std::endl;
}
std::string getText() const { return text; }
};
/**
* @brief 文本框控件
*
* 代表对话框中的文本输入框,可以输入和编辑文本。
*/
class TextBox : public Widget {
private:
std::string text;
public:
TextBox(const std::string& boxName) : Widget(boxName) {}
void setText(const std::string& newText) {
text = newText;
std::cout << "文本框 '" << name << "' 内容变为: " << text << std::endl;
onChange();
}
std::string getText() const { return text; }
void onChange() override {
if (mediator) {
mediator->widgetChanged(this);
}
}
void draw() override {
std::cout << "[文本框] " << name << ": " << text << std::endl;
}
};
/**
* @brief 复选框控件
*
* 代表对话框中的复选框,可以选中或取消选中。
*/
class CheckBox : public Widget {
private:
bool checked;
public:
CheckBox(const std::string& boxName) : Widget(boxName), checked(false) {}
void setChecked(bool isChecked) {
checked = isChecked;
std::cout << "复选框 '" << name << "' " << (checked ? "选中" : "取消选中") << std::endl;
onChange();
}
bool isChecked() const { return checked; }
void onChange() override {
if (mediator) {
mediator->widgetChanged(this);
}
}
void draw() override {
std::cout << "[复选框] " << name << " " << (checked ? "[✓]" : "[ ]") << std::endl;
}
};
/**
* @brief 具体对话框中介者
*
* 实现用户注册对话框的复杂交互逻辑。
* 协调各个控件之间的状态依赖关系。
*/
class RegistrationDialogMediator : public DialogMediator {
private:
std::vector<Widget*> widgets;
TextBox* usernameBox;
TextBox* passwordBox;
TextBox* emailBox;
CheckBox* agreeTermsCheck;
Button* submitButton;
public:
RegistrationDialogMediator()
: usernameBox(nullptr), passwordBox(nullptr), emailBox(nullptr),
agreeTermsCheck(nullptr), submitButton(nullptr) {}
void addWidget(Widget* widget) override {
widgets.push_back(widget);
widget->setMediator(this);
// 动态类型识别和绑定
if (auto textBox = dynamic_cast<TextBox*>(widget)) {
if (textBox->getName() == "用户名") usernameBox = textBox;
else if (textBox->getName() == "密码") passwordBox = textBox;
else if (textBox->getName() == "邮箱") emailBox = textBox;
} else if (auto checkBox = dynamic_cast<CheckBox*>(widget)) {
if (checkBox->getName() == "同意协议") agreeTermsCheck = checkBox;
} else if (auto button = dynamic_cast<Button*>(widget)) {
if (button->getName() == "提交按钮") submitButton = button;
}
}
void widgetChanged(Widget* widget) override {
std::cout << "\n=== 中介者处理变化: " << widget->getName() << " ===" << std::endl;
if (widget == usernameBox || widget == passwordBox || widget == emailBox) {
validateForm();
} else if (widget == agreeTermsCheck) {
handleAgreeTermsChange();
} else if (widget == submitButton) {
handleSubmit();
}
updateSubmitButton();
}
private:
void validateForm() {
std::cout << "正在进行表单验证..." << std::endl;
bool usernameValid = !usernameBox->getText().empty();
bool passwordValid = passwordBox->getText().length() >= 6;
bool emailValid = emailBox->getText().find('@') != std::string::npos;
std::cout << "用户名验证: " << (usernameValid ? "通过" : "失败") << std::endl;
std::cout << "密码验证: " << (passwordValid ? "通过" : "失败") << std::endl;
std::cout << "邮箱验证: " << (emailValid ? "通过" : "失败") << std::endl;
}
void handleAgreeTermsChange() {
std::cout << "协议同意状态变化: " << (agreeTermsCheck->isChecked() ? "已同意" : "未同意") << std::endl;
}
void handleSubmit() {
if (submitButton->isEnabled()) {
std::cout << "执行提交操作..." << std::endl;
std::cout << "用户名: " << usernameBox->getText() << std::endl;
std::cout << "邮箱: " << emailBox->getText() << std::endl;
std::cout << "注册成功!" << std::endl;
} else {
std::cout << "提交按钮被禁用,无法提交" << std::endl;
}
}
void updateSubmitButton() {
if (usernameBox && passwordBox && emailBox && agreeTermsCheck && submitButton) {
bool canSubmit = !usernameBox->getText().empty() &&
passwordBox->getText().length() >= 6 &&
emailBox->getText().find('@') != std::string::npos &&
agreeTermsCheck->isChecked();
submitButton->setEnabled(canSubmit);
std::cout << "提交按钮状态: " << (canSubmit ? "启用" : "禁用") << std::endl;
}
}
};
// 演示代码
int main() {
// 创建对话框中介者
auto dialogMediator = std::make_unique<RegistrationDialogMediator>();
// 创建对话框控件
auto usernameBox = std::make_unique<TextBox>("用户名");
auto passwordBox = std::make_unique<TextBox>("密码");
auto emailBox = std::make_unique<TextBox>("邮箱");
auto agreeCheck = std::make_unique<CheckBox>("同意协议");
auto submitButton = std::make_unique<Button>("提交按钮", "注册");
// 将控件添加到中介者
dialogMediator->addWidget(usernameBox.get());
dialogMediator->addWidget(passwordBox.get());
dialogMediator->addWidget(emailBox.get());
dialogMediator->addWidget(agreeCheck.get());
dialogMediator->addWidget(submitButton.get());
std::cout << "=== 用户注册对话框演示 ===" << std::endl;
// 模拟用户交互
usernameBox->setText("张三");
passwordBox->setText("123456");
emailBox->setText("zhangsan@example.com");
agreeCheck->setChecked(true);
std::cout << "\n--- 尝试提交 ---" << std::endl;
submitButton->onClick();
std::cout << "\n--- 测试验证失败 ---" << std::endl;
passwordBox->setText("123"); // 密码太短
submitButton->onClick();
return 0;
}
对话框交互流程图:
文本框 复选框 按钮 用户输入文本 文本框触发onChange 中介者接收变化通知 判断变化来源 执行表单验证 更新协议状态 处理提交逻辑 更新提交按钮状态 执行注册业务 界面状态更新
3.3 案例3:微服务架构中的API网关
应用场景:在微服务架构中,API网关作为中介者协调各个微服务间的通信。
简化版代码实现:
cpp
#include <iostream>
#include <string>
#include <map>
#include <memory>
/**
* @brief 微服务接口
*
* 定义微服务的基本操作,每个微服务提供特定的业务功能。
*/
class Microservice {
protected:
std::string serviceName;
public:
Microservice(const std::string& name) : serviceName(name) {}
virtual ~Microservice() = default;
virtual std::string handleRequest(const std::string& request) = 0;
std::string getName() const { return serviceName; }
};
/**
* @brief 用户服务
*
* 处理用户相关的业务逻辑,如注册、登录、查询用户信息等。
*/
class UserService : public Microservice {
public:
UserService() : Microservice("UserService") {}
std::string handleRequest(const std::string& request) override {
if (request.find("getUser") != std::string::npos) {
return "用户信息: {id: 123, name: '张三'}";
} else if (request.find("login") != std::string::npos) {
return "登录成功,token: abc123";
}
return "未知用户请求";
}
};
/**
* @brief 订单服务
*
* 处理订单相关的业务逻辑,如创建订单、查询订单、取消订单等。
*/
class OrderService : public Microservice {
public:
OrderService() : Microservice("OrderService") {}
std::string handleRequest(const std::string& request) override {
if (request.find("createOrder") != std::string::npos) {
return "订单创建成功,订单号: ORD2024001";
} else if (request.find("getOrder") != std::string::npos) {
return "订单信息: {id: 456, amount: 299.00}";
}
return "未知订单请求";
}
};
/**
* @brief 支付服务
*
* 处理支付相关的业务逻辑,如发起支付、查询支付状态、退款等。
*/
class PaymentService : public Microservice {
public:
PaymentService() : Microservice("PaymentService") {}
std::string handleRequest(const std::string& request) override {
if (request.find("processPayment") != std::string::npos) {
return "支付成功,交易号: PAY2024001";
} else if (request.find("refund") != std::string::npos) {
return "退款处理中";
}
return "未知支付请求";
}
};
/**
* @brief API网关(中介者)
*
* 作为微服务架构的中介者,负责请求路由、认证、限流、日志等跨领域关注点。
* 客户端只需与网关交互,无需了解后端微服务的具体位置和实现。
*/
class ApiGateway {
private:
std::map<std::string, std::shared_ptr<Microservice>> services;
public:
void registerService(const std::string& route, std::shared_ptr<Microservice> service) {
services[route] = service;
std::cout << "注册服务: " << route << " -> " << service->getName() << std::endl;
}
std::string handleRequest(const std::string& route, const std::string& request) {
std::cout << "\n=== API网关处理请求 ===" << std::endl;
std::cout << "路由: " << route << std::endl;
std::cout << "请求: " << request << std::endl;
// 认证检查
if (!authenticate(request)) {
return "错误: 认证失败";
}
// 限流检查
if (!rateLimit(route)) {
return "错误: 请求过于频繁";
}
// 路由到对应的微服务
auto it = services.find(route);
if (it != services.end()) {
std::cout << "路由到服务: " << it->second->getName() << std::endl;
return it->second->handleRequest(request);
} else {
return "错误: 未找到对应的服务";
}
}
private:
bool authenticate(const std::string& request) {
// 简化的认证逻辑
bool authenticated = request.find("token=") != std::string::npos;
std::cout << "认证结果: " << (authenticated ? "通过" : "失败") << std::endl;
return authenticated;
}
bool rateLimit(const std::string& route) {
// 简化的限流逻辑
std::cout << "限流检查: 通过" << std::endl;
return true;
}
};
// 演示代码
int main() {
// 创建API网关(中介者)
ApiGateway gateway;
// 创建微服务
auto userService = std::make_shared<UserService>();
auto orderService = std::make_shared<OrderService>();
auto paymentService = std::make_shared<PaymentService>();
// 注册服务到网关
gateway.registerService("/api/users", userService);
gateway.registerService("/api/orders", orderService);
gateway.registerService("/api/payments", paymentService);
std::cout << "=== 微服务API网关演示 ===" << std::endl;
// 模拟客户端请求
std::cout << "\n1. 用户登录请求:" << std::endl;
std::string response1 = gateway.handleRequest("/api/users", "action=login&token=abc123");
std::cout << "响应: " << response1 << std::endl;
std::cout << "\n2. 创建订单请求:" << std::endl;
std::string response2 = gateway.handleRequest("/api/orders", "action=createOrder&token=abc123");
std::cout << "响应: " << response2 << std::endl;
std::cout << "\n3. 支付处理请求:" << std::endl;
std::string response3 = gateway.handleRequest("/api/payments", "action=processPayment&token=abc123");
std::cout << "响应: " << response3 << std::endl;
std::cout << "\n4. 未认证请求测试:" << std::endl;
std::string response4 = gateway.handleRequest("/api/users", "action=getUser");
std::cout << "响应: " << response4 << std::endl;
return 0;
}
4. 编译与运行指南
4.1 Makefile范例
makefile
# 编译器设置
CXX := g++
CXXFLAGS := -std=c++17 -Wall -Wextra -O2
TARGET := mediator_demo
# 源文件
SOURCES := chat_mediator.cpp dialog_mediator.cpp api_gateway.cpp
OBJECTS := $(SOURCES:.cpp=.o)
# 默认目标
all: $(TARGET)
# 链接目标文件
$(TARGET): $(OBJECTS)
$(CXX) $(CXXFLAGS) -o $@ $^
# 编译源文件
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
# 清理生成文件
clean:
rm -f $(OBJECTS) $(TARGET)
# 运行程序
run: $(TARGET)
./$(TARGET)
# 调试编译
debug: CXXFLAGS += -g -DDEBUG
debug: $(TARGET)
.PHONY: all clean run debug
4.2 编译与运行方法
编译步骤:
bash
# 1. 保存代码文件
# 将上述代码分别保存为 chat_mediator.cpp, dialog_mediator.cpp, api_gateway.cpp
# 2. 编译程序
make
# 3. 运行演示
make run
输出结果解读:
=== 聊天室演示开始 ===
Alice 尝试发送消息...
--- 消息路由开始 ---
发送者: Alice
消息内容: 大家好,我是Alice!
接收者: 所有在线用户 [广播]
-> 发送给: Bob
-> 发送给: Charlie
-> 发送给: 管理员
--- 消息路由结束 ---
- 展示了消息通过中介者进行路由的过程
- 显示了广播消息和私聊消息的不同处理逻辑
- 体现了中介者集中控制的好处
5. 中介者模式的变体与演进
5.1 事件总线模式(Event Bus)
现代中介者模式的演进:事件总线提供了更松散的耦合:
cpp
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <functional>
/**
* @brief 事件总线(高级中介者)
*
* 基于发布-订阅模式的中介者变体,组件间完全解耦。
* 组件通过事件进行通信,无需知道事件的处理者。
*/
class EventBus {
private:
std::map<std::string, std::vector<std::function<void(const std::string&)>>> subscribers;
public:
void subscribe(const std::string& eventType, std::function<void(const std::string&)> handler) {
subscribers[eventType].push_back(handler);
}
void publish(const std::string& eventType, const std::string& data) {
auto it = subscribers.find(eventType);
if (it != subscribers.end()) {
for (auto& handler : it->second) {
handler(data);
}
}
}
};
// 使用事件总线的组件
class ComponentA {
public:
void sendMessage(EventBus& bus, const std::string& message) {
bus.publish("message_event", message);
}
};
class ComponentB {
public:
ComponentB(EventBus& bus) {
bus.subscribe("message_event", [this](const std::string& data) {
this->onMessageReceived(data);
});
}
void onMessageReceived(const std::string& message) {
std::cout << "ComponentB 收到消息: " << message << std::endl;
}
};
5.2 中介者模式与相关模式对比
模式 | 关注点 | 耦合度 | 适用场景 |
---|---|---|---|
中介者模式 | 对象间交互的集中管理 | 低(通过中介者) | 复杂交互的组件群 |
观察者模式 | 一对多的依赖关系 | 较低(主题与观察者) | 事件通知系统 |
外观模式 | 简化复杂子系统接口 | 低(客户端与子系统) | 子系统接口简化 |
代理模式 | 控制对象访问 | 较低(客户端与真实对象) | 访问控制、延迟加载 |
6. 总结与最佳实践
中介者模式经过几十年的发展,已经从简单的对象协调演变为现代架构的核心组件。它的核心价值体现在:
6.1 适用场景总结
- 复杂UI交互:对话框、表单等包含多个相互依赖的控件
- 聊天系统:多个用户间的消息路由和协调
- 微服务架构:API网关作为服务间通信的中介者
- 游戏开发:游戏对象间的交互协调
- 工作流引擎:协调各个处理节点的工作流程
6.2 最佳实践指南
何时使用中介者模式:
- 对象间存在复杂的网状依赖关系
- 组件间的交互逻辑经常变化
- 需要集中控制组件间的通信
- 系统需要良好的可扩展性和可维护性
何时避免使用中介者模式:
- 组件间交互非常简单直接
- 性能要求极高的场景(中介者可能引入开销)
- 组件数量很少,交互关系简单
6.3 现代演进趋势
随着响应式编程和微服务架构的流行,中介者模式以新的形式继续发挥价值:
- 前端框架:React/Vue中的状态管理(Redux/Vuex)本质上是中介者
- 后端架构:消息队列、服务网格都是中介者思想的体现
- 云原生:Service Mesh作为微服务通信的中介者层
中介者模式不仅是23种设计模式中的重要成员,更是构建可维护、可扩展软件系统的关键工具。掌握中介者模式,意味着掌握了管理复杂对象交互的"交通指挥艺术"。