设计模式(C++)详解——中介者模式(1)

<摘要>

中介者模式就像是软件世界中的"交通警察",它站在复杂的对象交叉路口,指挥着各个对象之间的通信流向。想象一下,如果没有交通警察,每个司机都要直接与其他所有司机协商通行顺序,那将是多么混乱的场景!中介者模式正是为了解决这种对象间复杂网状依赖关系而生的。本文将带你深入了解这个巧妙的设计模式,从它的诞生背景到现代应用,通过生动的现实案例(包括空中交通管制、聊天室系统等)展示其强大威力。我们还会亲手实现完整的中介者系统,用直观的图表揭示其工作原理。


<解析>

中介者模式深度解析:软件架构的"交通指挥官"

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 适用场景总结

  1. 复杂UI交互:对话框、表单等包含多个相互依赖的控件
  2. 聊天系统:多个用户间的消息路由和协调
  3. 微服务架构:API网关作为服务间通信的中介者
  4. 游戏开发:游戏对象间的交互协调
  5. 工作流引擎:协调各个处理节点的工作流程

6.2 最佳实践指南

何时使用中介者模式

  • 对象间存在复杂的网状依赖关系
  • 组件间的交互逻辑经常变化
  • 需要集中控制组件间的通信
  • 系统需要良好的可扩展性和可维护性

何时避免使用中介者模式

  • 组件间交互非常简单直接
  • 性能要求极高的场景(中介者可能引入开销)
  • 组件数量很少,交互关系简单

6.3 现代演进趋势

随着响应式编程和微服务架构的流行,中介者模式以新的形式继续发挥价值:

  • 前端框架:React/Vue中的状态管理(Redux/Vuex)本质上是中介者
  • 后端架构:消息队列、服务网格都是中介者思想的体现
  • 云原生:Service Mesh作为微服务通信的中介者层

中介者模式不仅是23种设计模式中的重要成员,更是构建可维护、可扩展软件系统的关键工具。掌握中介者模式,意味着掌握了管理复杂对象交互的"交通指挥艺术"。

相关推荐
大飞pkz2 小时前
【设计模式】中介者模式
开发语言·设计模式·c#·中介者模式
tpoog2 小时前
[C++项目框架]gflags和gtest的简单介绍
开发语言·c++
Q741_1472 小时前
C++ 位运算 高频面试考点 力扣 268. 丢失的数字 题解 每日一题
c++·算法·leetcode·面试·位运算
电子_咸鱼2 小时前
LeetCode-hot100——验证二叉搜索树
开发语言·数据结构·c++·算法·leetcode·深度优先
Imxyk3 小时前
Codeforces Round 1052 (Div. 2) C. Wrong Binary Searchong Binary Search
c语言·c++·算法
liu****3 小时前
负载均衡式的在线OJ项目编写(五)
运维·c++·负载均衡·个人开发
saber_andlibert4 小时前
【Linux】深入理解Linux的进程(一)
linux·运维·服务器·开发语言·c++
YXXY3136 小时前
算法练习(C++)---双指针
c++
玖笙&9 小时前
✨WPF编程基础【1.3】:XAML 名称空间
c++·wpf·visual studio