C++ 中介者模式详解

循以下设计原则:

  1. 单一职责原则:将对象间的交互集中到中介者中

  2. 迪米特法则:减少对象间的直接通信

  3. 开闭原则:可以新增中介者而不修改现有组件

主要优点

  1. 降低耦合:减少对象间的直接依赖

  2. 集中控制:将交互逻辑集中到中介者

  3. 简化维护:交互关系更容易理解和修改

  4. 复用性:组件可以更容易地被复用

模式结构

主要组件

  1. Mediator(中介者接口)

    • 定义与各组件通信的接口
  2. ConcreteMediator(具体中介者)

    • 实现中介者接口

    • 协调各组件之间的交互

    • 知道所有组件及其用途

  3. Component(组件)

    • 每个组件都知道其中介者对象

    • 组件间不直接通信,而是通过中介者

完整代码示例

复制代码
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <algorithm>

// 前置声明
class Component;

// ==================== 中介者接口 ====================
class Mediator {
public:
    virtual void notify(Component* sender, const std::string& event) const = 0;
    virtual ~Mediator() = default;
};

// ==================== 组件基类 ====================
class Component {
protected:
    Mediator* mediator_;
    
public:
    explicit Component(Mediator* mediator = nullptr) : mediator_(mediator) {}
    
    void setMediator(Mediator* mediator) {
        mediator_ = mediator;
    }
    
    virtual ~Component() = default;
};

// ==================== 具体组件 ====================
class Button : public Component {
    std::string name_;
    
public:
    explicit Button(const std::string& name, Mediator* mediator = nullptr)
        : Component(mediator), name_(name) {}
    
    void click() {
        std::cout << name_ << " 被点击" << std::endl;
        if (mediator_) {
            mediator_->notify(this, "click");
        }
    }
};

class TextBox : public Component {
    std::string text_;
    
public:
    explicit TextBox(Mediator* mediator = nullptr) : Component(mediator) {}
    
    void setText(const std::string& text) {
        text_ = text;
        std::cout << "文本框内容设置为: " << text << std::endl;
        if (mediator_) {
            mediator_->notify(this, "text_changed");
        }
    }
    
    std::string getText() const { return text_; }
};

class CheckBox : public Component {
    bool checked_ = false;
    
public:
    explicit CheckBox(Mediator* mediator = nullptr) : Component(mediator) {}
    
    void check() {
        checked_ = !checked_;
        std::cout << "复选框状态: " << (checked_ ? "选中" : "未选中") << std::endl;
        if (mediator_) {
            mediator_->notify(this, checked_ ? "checked" : "unchecked");
        }
    }
    
    bool isChecked() const { return checked_; }
};

// ==================== 具体中介者 ====================
class AuthenticationDialog : public Mediator {
    Button* loginButton_;
    Button* cancelButton_;
    TextBox* usernameTextBox_;
    TextBox* passwordTextBox_;
    CheckBox* rememberMeCheckBox_;
    
public:
    AuthenticationDialog(
        Button* loginButton,
        Button* cancelButton,
        TextBox* usernameTextBox,
        TextBox* passwordTextBox,
        CheckBox* rememberMeCheckBox)
        : loginButton_(loginButton),
          cancelButton_(cancelButton),
          usernameTextBox_(usernameTextBox),
          passwordTextBox_(passwordTextBox),
          rememberMeCheckBox_(rememberMeCheckBox) {
        
        loginButton_->setMediator(this);
        cancelButton_->setMediator(this);
        usernameTextBox_->setMediator(this);
        passwordTextBox_->setMediator(this);
        rememberMeCheckBox_->setMediator(this);
    }
    
    void notify(Component* sender, const std::string& event) const override {
        if (sender == loginButton_ && event == "click") {
            std::cout << "登录按钮点击 - 尝试登录..." << std::endl;
            if (usernameTextBox_->getText().empty() || passwordTextBox_->getText().empty()) {
                std::cout << "错误: 用户名和密码不能为空" << std::endl;
            } else {
                std::cout << "使用用户名 '" << usernameTextBox_->getText() 
                          << "' 和密码 '" << passwordTextBox_->getText() << "' 登录" << std::endl;
                if (rememberMeCheckBox_->isChecked()) {
                    std::cout << "记住登录状态" << std::endl;
                }
            }
        } else if (sender == cancelButton_ && event == "click") {
            std::cout << "取消按钮点击 - 重置表单" << std::endl;
            usernameTextBox_->setText("");
            passwordTextBox_->setText("");
            rememberMeCheckBox_->check();
        } else if (sender == rememberMeCheckBox_ && (event == "checked" || event == "unchecked")) {
            std::cout << "记住我选项改变: " << event << std::endl;
        } else if ((sender == usernameTextBox_ || sender == passwordTextBox_) 
                  && event == "text_changed") {
            std::cout << "文本改变 - 验证输入..." << std::endl;
        }
    }
};

// ==================== 客户端代码 ====================
int main() {
    std::cout << "=== 中介者模式演示: 登录对话框 ===" << std::endl;
    
    // 创建组件
    Button loginButton("登录");
    Button cancelButton("取消");
    TextBox usernameTextBox;
    TextBox passwordTextBox;
    CheckBox rememberMeCheckBox;
    
    // 创建中介者并关联组件
    AuthenticationDialog dialog(
        &loginButton, 
        &cancelButton, 
        &usernameTextBox, 
        &passwordTextBox, 
        &rememberMeCheckBox);
    
    // 模拟用户交互
    std::cout << "\n用户输入用户名和密码..." << std::endl;
    usernameTextBox.setText("user123");
    passwordTextBox.setText("password");
    
    std::cout << "\n用户点击记住我..." << std::endl;
    rememberMeCheckBox.check();
    
    std::cout << "\n用户点击登录按钮..." << std::endl;
    loginButton.click();
    
    std::cout << "\n用户点击取消按钮..." << std::endl;
    cancelButton.click();
    
    return 0;
}

模式变体

1. 观察者中介者

复制代码
class ObserverMediator : public Mediator {
    std::vector<Component*> components_;
    
public:
    void addComponent(Component* component) {
        components_.push_back(component);
        component->setMediator(this);
    }
    
    void notify(Component* sender, const std::string& event) override {
        for (auto component : components_) {
            if (component != sender) {
                // 通知其他组件
            }
        }
    }
};

2. 单例中介者

复制代码
class SingletonMediator : public Mediator {
    static SingletonMediator* instance_;
    SingletonMediator() = default;
    
public:
    static SingletonMediator* getInstance() {
        if (!instance_) {
            instance_ = new SingletonMediator();
        }
        return instance_;
    }
    
    void notify(Component* sender, const std::string& event) override {
        // 实现通知逻辑
    }
};

实际应用场景

  1. GUI开发:如示例中的对话框组件交互

  2. 聊天系统:聊天室作为用户间通信的中介

  3. 航空管制:塔台协调飞机间的通信

  4. 工作流系统:协调多个处理步骤

  5. 游戏开发:游戏对象间的交互协调

相关推荐
碎梦归途13 天前
23种设计模式-行为型模式之中介者模式(Java版本)
java·jvm·设计模式·中介者模式·软件设计师
程序员JerrySUN13 天前
设计模式每日硬核训练 Day 17:中介者模式(Mediator Pattern)完整讲解与实战应用
microsoft·设计模式·中介者模式
CHQIUU15 天前
Java 设计模式心法之第25篇 - 中介者 (Mediator) - 用“中央协调”降低对象间耦合度
java·设计模式·中介者模式
Pasregret18 天前
中介者模式:解耦对象间复杂交互的设计模式
设计模式·交互·中介者模式
听闻风很好吃1 个月前
Java设计模式之中介者模式:从入门到架构级实践
java·设计模式·中介者模式
搞不懂语言的程序员1 个月前
中介者模式详解及真实场景解决方案
设计模式·中介者模式
cijiancao2 个月前
23种设计模式中的中介者模式
java·设计模式·中介者模式
赤水无泪2 个月前
行为模式---中介者模式
中介者模式