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

<摘要>
中介者模式是一种行为设计模式,通过引入中介者对象来封装一组对象之间的交互,从而降低对象间的耦合度。本文将详细解析中介者模式的背景概念、设计意图、实现方式及应用场景,通过聊天室系统、飞机调度系统和UI组件交互三个完整案例,结合C++代码实现和Mermaid图表,全面展示该模式的实际应用价值。


<解析>

中介者模式深度解析

1. 背景与核心概念

1.1 起源与发展历程

中介者模式的诞生可以追溯到软件工程中"高内聚、低耦合"的设计原则。在早期的面向对象设计中,开发人员经常遇到这样的困境:当多个对象需要相互通信时,直接的对象引用会导致复杂的网状依赖关系。

发展脉络

  • 1987年:在Smalltalk语言的MVC框架中首次出现了类似中介者的概念
  • 1994年:Gamma等人在《设计模式》一书中正式提出并定义了中介者模式
  • 2000年代:随着GUI框架和企业级应用的发展,中介者模式得到广泛应用
  • 现今:在微服务架构、事件驱动系统中,中介者模式的思想被重新诠释和应用

1.2 核心概念解析

中介者模式的核心思想是:用一个中介对象来封装一系列的对象交互,使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互

关键术语

术语英文说明
中介者Mediator定义对象间交互的接口
具体中介者ConcreteMediator实现中介者接口,协调各同事对象
同事类Colleague定义同事类的接口,持有中介者引用
具体同事类ConcreteColleague实现同事类接口,只与中介者通信

1.3 UML类图解析

knows
mediator
«abstract»
Mediator
+notify(sender Colleague, event string) : void
ConcreteMediator
-colleague1 ConcreteColleague1
-colleague2 ConcreteColleague2
-colleague3 ConcreteColleague3
+notify(sender Colleague, event string) : void
+registerColleague1(colleague ConcreteColleague1) : void
+registerColleague2(colleague ConcreteColleague2) : void
+registerColleague3(colleague ConcreteColleague3) : void
«abstract»
Colleague
#mediator Mediator
+setMediator(mediator Mediator) : void
+send(message string) : void
+receive(message string) : void
ConcreteColleague1
-name string
+ConcreteColleague1(name string)
+send(message string) : void
+receive(message string) : void
ConcreteColleague2
-name string
+ConcreteColleague2(name string)
+send(message string) : void
+receive(message string) : void
ConcreteColleague3
-name string
+ConcreteColleague3(name string)
+send(message string) : void
+receive(message string) : void

图表解读

  • Mediator:抽象中介者,定义通信接口
  • ConcreteMediator:具体中介者,维护同事对象引用,实现复杂的协调逻辑
  • Colleague:同事抽象类,包含中介者引用
  • ConcreteColleague:具体同事类,通过中介者与其他对象通信

2. 设计意图与考量

2.1 核心设计目标

中介者模式的核心设计目标可以用"解耦"二字概括,具体体现在:

  1. 降低耦合度:将网状依赖变为星状依赖
  2. 集中控制:将交互逻辑集中到中介者中
  3. 简化对象职责:每个对象只需关注自身业务逻辑
  4. 提高复用性:同事类可以独立复用

2.2 设计权衡因素

优势

  • ✅ 减少类间依赖,降低耦合
  • ✅ 简化对象协议,一对多交互变为一对一
  • ✅ 抽象对象交互,便于理解和维护
  • ✅ 符合迪米特法则(最少知识原则)

劣势

  • ❌ 中介者可能变得过于复杂,成为"上帝对象"
  • ❌ 增加了系统的中间层,可能影响性能
  • ❌ 中介者本身的修改可能影响整个系统

2.3 适用场景分析

适合使用中介者模式的场景

  • 对象间存在复杂的网状引用关系
  • 一个对象引用很多其他对象,直接通信导致难以复用
  • 想在多个对象间定制交互行为,又不想生成太多子类
  • 交互行为需要定义在不同对象间,但又不想分散在各个类中

3. 实例与应用场景

3.1 案例一:智能聊天室系统

场景描述
设计一个多人聊天室系统,用户可以向所有人广播消息,也可以私聊特定用户,同时需要支持用户加入、离开的通知。

实现方案

#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
#include <memory>

// 前向声明
class User;

/**
 * @brief 聊天室中介者接口
 * 
 * 定义用户间通信的标准接口,负责协调所有用户对象之间的交互
 */
class ChatMediator {
public:
    virtual ~ChatMediator() = default;
    
    /**
     * @brief 发送消息到所有用户
     * 
     * @param message 消息内容
     * @param sender 发送者
     */
    virtual void broadcastMessage(const std::string& message, 
                                 const std::string& sender) = 0;
    
    /**
     * @brief 发送私聊消息
     * 
     * @param message 消息内容
     * @param sender 发送者
     * @param receiver 接收者
     */
    virtual void privateMessage(const std::string& message,
                               const std::string& sender,
                               const std::string& receiver) = 0;
    
    /**
     * @brief 用户加入聊天室
     * 
     * @param user 用户对象
     */
    virtual void addUser(std::shared_ptr<User> user) = 0;
    
    /**
     * @brief 用户离开聊天室
     * 
     * @param username 用户名
     */
    virtual void removeUser(const std::string& username) = 0;
};

/**
 * @brief 用户抽象类(同事类)
 * 
 * 定义用户的基本行为和属性,持有中介者引用
 */
class User {
protected:
    std::string username_;
    std::shared_ptr<ChatMediator> mediator_;

public:
    User(const std::string& username, std::shared_ptr<ChatMediator> mediator)
        : username_(username), mediator_(mediator) {}
    
    virtual ~User() = default;
    
    /**
     * @brief 获取用户名
     * 
     * @return std::string 用户名
     */
    std::string getUsername() const { return username_; }
    
    /**
     * @brief 发送广播消息
     * 
     * @param message 消息内容
     */
    virtual void sendMessage(const std::string& message) {
        std::cout << username_ << " 发送广播: " << message << std::endl;
        mediator_->broadcastMessage(message, username_);
    }
    
    /**
     * @brief 发送私聊消息
     * 
     * @param message 消息内容
     * @param receiver 接收者用户名
     */
    virtual void sendPrivateMessage(const std::string& message, 
                                   const std::string& receiver) {
        std::cout << username_ << " 私聊 " << receiver << ": " << message << std::endl;
        mediator_->privateMessage(message, username_, receiver);
    }
    
    /**
     * @brief 接收消息
     * 
     * @param message 消息内容
     * @param sender 发送者
     */
    virtual void receiveMessage(const std::string& message, 
                               const std::string& sender) = 0;
};

/**
 * @brief 具体用户类
 * 
 * 实现具体的用户行为,可以扩展不同的用户类型
 */
class ChatUser : public User {
public:
    ChatUser(const std::string& username, std::shared_ptr<ChatMediator> mediator)
        : User(username, mediator) {}
    
    void receiveMessage(const std::string& message, 
                       const std::string& sender) override {
        std::cout << username_ << " 收到来自 " << sender << " 的消息: " 
                  << message << std::endl;
    }
};

/**
 * @brief 具体聊天室中介者
 * 
 * 实现聊天室的具体逻辑,管理所有用户和消息路由
 */
class ConcreteChatMediator : public ChatMediator {
private:
    std::unordered_map<std::string, std::shared_ptr<User>> users_;
    
public:
    void broadcastMessage(const std::string& message, 
                         const std::string& sender) override {
        std::cout << "=== 聊天室广播 === (" << sender << "): " 
                  << message << std::endl;
        
        for (const auto& pair : users_) {
            if (pair.first != sender) {  // 不发送给自己
                pair.second->receiveMessage(message, sender);
            }
        }
    }
    
    void privateMessage(const std::string& message,
                       const std::string& sender,
                       const std::string& receiver) override {
        std::cout << "=== 私聊消息 === [" << sender << " -> " 
                  << receiver << "]: " << message << std::endl;
        
        auto it = users_.find(receiver);
        if (it != users_.end()) {
            it->second->receiveMessage("[私聊] " + message, sender);
        } else {
            // 通知发送者接收者不存在
            auto senderIt = users_.find(sender);
            if (senderIt != users_.end()) {
                senderIt->second->receiveMessage("错误: 用户 " + receiver + " 不存在", "系统");
            }
        }
    }
    
    void addUser(std::shared_ptr<User> user) override {
        std::string username = user->getUsername();
        users_[username] = user;
        
        // 通知所有用户有新用户加入
        broadcastMessage("用户 " + username + " 加入了聊天室", "系统");
    }
    
    void removeUser(const std::string& username) override {
        auto it = users_.find(username);
        if (it != users_.end()) {
            users_.erase(it);
            broadcastMessage("用户 " + username + " 离开了聊天室", "系统");
        }
    }
};

// 演示代码
int main() {
    // 创建聊天室中介者
    auto chatMediator = std::make_shared<ConcreteChatMediator>();
    
    // 创建用户
    auto user1 = std::make_shared<ChatUser>("Alice", chatMediator);
    auto user2 = std::make_shared<ChatUser>("Bob", chatMediator);
    auto user3 = std::make_shared<ChatUser>("Charlie", chatMediator);
    
    // 用户加入聊天室
    chatMediator->addUser(user1);
    chatMediator->addUser(user2);
    chatMediator->addUser(user3);
    
    std::cout << "\n=== 聊天开始 ===\n" << std::endl;
    
    // 用户间通信
    user1->sendMessage("大家好!");
    user2->sendMessage("你好,Alice!");
    user1->sendPrivateMessage("嘿,Bob,有个秘密要告诉你", "Bob");
    user3->sendMessage("我也可以看到广播消息");
    
    // Bob离开聊天室
    chatMediator->removeUser("Bob");
    
    // 再次尝试给Bob发消息
    user1->sendPrivateMessage("Bob,你还在吗?", "Bob");
    
    return 0;
}

时序图分析

AliceChatMediatorBobCharlie用户加入聊天室addUser(Alice)receiveMessage("Alice加入", "系统")receiveMessage("Alice加入", "系统")广播消息流程sendMessage("大家好!")receiveMessage("大家好!", "Alice")receiveMessage("大家好!", "Alice")私聊消息流程sendPrivateMessage("秘密", "Bob")receiveMessage("[私聊] 秘密", "Alice")用户离开removeUser("Bob")receiveMessage("Bob离开", "系统")receiveMessage("Bob离开", "系统")AliceChatMediatorBobCharlie

3.2 案例二:飞机调度系统

场景描述
设计一个航空管制系统,多架飞机需要与塔台通信,飞机之间不能直接通信,必须通过塔台中介者来协调起飞、降落和航线冲突。

#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <algorithm>

// 飞机状态枚举
enum class FlightStatus {
    ON_GROUND,
    TAKING_OFF,
    IN_AIR,
    LANDING
};

/**
 * @brief 航空管制中介者接口
 * 
 * 协调所有飞机的起降和飞行状态,避免冲突
 */
class AirTrafficControl {
public:
    virtual ~AirTrafficControl() = default;
    
    /**
     * @brief 请求起飞
     * 
     * @param flightId 航班号
     * @return bool 是否允许起飞
     */
    virtual bool requestTakeoff(const std::string& flightId) = 0;
    
    /**
     * @brief 请求降落
     * 
     * @param flightId 航班号
     * @return bool 是否允许降落
     */
    virtual bool requestLanding(const std::string& flightId) = 0;
    
    /**
     * @brief 通知起飞完成
     * 
     * @param flightId 航班号
     */
    virtual void notifyTakeoffComplete(const std::string& flightId) = 0;
    
    /**
     * @brief 通知降落完成
     * 
     * @param flightId 航班号
     */
    virtual void notifyLandingComplete(const std::string& flightId) = 0;
    
    /**
     * @brief 注册飞机
     * 
     * @param aircraft 飞机对象
     */
    virtual void registerAircraft(std::shared_ptr<class Aircraft> aircraft) = 0;
};

/**
 * @brief 飞机抽象类
 * 
 * 定义飞机的基本行为和状态
 */
class Aircraft {
protected:
    std::string flightId_;
    FlightStatus status_;
    std::shared_ptr<AirTrafficControl> atc_;

public:
    Aircraft(const std::string& flightId, std::shared_ptr<AirTrafficControl> atc)
        : flightId_(flightId), status_(FlightStatus::ON_GROUND), atc_(atc) {}
    
    virtual ~Aircraft() = default;
    
    std::string getFlightId() const { return flightId_; }
    FlightStatus getStatus() const { return status_; }
    
    /**
     * @brief 请求起飞
     */
    virtual void requestTakeoff() {
        std::cout << "航班 " << flightId_ << " 请求起飞" << std::endl;
        if (atc_->requestTakeoff(flightId_)) {
            status_ = FlightStatus::TAKING_OFF;
            std::cout << "航班 " << flightId_ << " 开始起飞" << std::endl;
        } else {
            std::cout << "航班 " << flightId_ << " 起飞请求被拒绝" << std::endl;
        }
    }
    
    /**
     * @brief 请求降落
     */
    virtual void requestLanding() {
        std::cout << "航班 " << flightId_ << " 请求降落" << std::endl;
        if (atc_->requestLanding(flightId_)) {
            status_ = FlightStatus::LANDING;
            std::cout << "航班 " << flightId_ << " 开始降落" << std::endl;
        } else {
            std::cout << "航班 " << flightId_ << " 降落请求被拒绝" << std::endl;
        }
    }
    
    /**
     * @brief 通知起飞完成
     */
    virtual void notifyTakeoffComplete() {
        status_ = FlightStatus::IN_AIR;
        atc_->notifyTakeoffComplete(flightId_);
        std::cout << "航班 " << flightId_ << " 起飞完成,正在飞行" << std::endl;
    }
    
    /**
     * @brief 通知降落完成
     */
    virtual void notifyLandingComplete() {
        status_ = FlightStatus::ON_GROUND;
        atc_->notifyLandingComplete(flightId_);
        std::cout << "航班 " << flightId_ << " 降落完成" << std::endl;
    }
};

/**
 * @brief 具体飞机类
 */
class CommercialAircraft : public Aircraft {
public:
    CommercialAircraft(const std::string& flightId, 
                      std::shared_ptr<AirTrafficControl> atc)
        : Aircraft(flightId, atc) {}
};

/**
 * @brief 具体航空管制中介者
 */
class ConcreteATC : public AirTrafficControl {
private:
    std::vector<std::shared_ptr<Aircraft>> aircrafts_;
    int runwayInUse_;  // 跑道使用状态
    
public:
    ConcreteATC() : runwayInUse_(-1) {}
    
    bool requestTakeoff(const std::string& flightId) override {
        // 检查跑道是否被占用
        if (runwayInUse_ != -1) {
            std::cout << "塔台回复 " << flightId << ": 跑道忙碌,请等待" << std::endl;
            return false;
        }
        
        // 分配跑道
        for (size_t i = 0; i < aircrafts_.size(); ++i) {
            if (aircrafts_[i]->getFlightId() == flightId) {
                runwayInUse_ = i;
                std::cout << "塔台回复 " << flightId << ": 允许起飞,使用跑道" << std::endl;
                return true;
            }
        }
        
        return false;
    }
    
    bool requestLanding(const std::string& flightId) override {
        // 检查跑道是否被占用
        if (runwayInUse_ != -1) {
            std::cout << "塔台回复 " << flightId << ": 跑道忙碌,请盘旋等待" << std::endl;
            return false;
        }
        
        // 分配跑道
        for (size_t i = 0; i < aircrafts_.size(); ++i) {
            if (aircrafts_[i]->getFlightId() == flightId) {
                runwayInUse_ = i;
                std::cout << "塔台回复 " << flightId << ": 允许降落,使用跑道" << std::endl;
                return true;
            }
        }
        
        return false;
    }
    
    void notifyTakeoffComplete(const std::string& flightId) override {
        std::cout << "塔台确认: " << flightId << " 起飞完成,释放跑道" << std::endl;
        runwayInUse_ = -1;
    }
    
    void notifyLandingComplete(const std::string& flightId) override {
        std::cout << "塔台确认: " << flightId << " 降落完成,释放跑道" << std::endl;
        runwayInUse_ = -1;
    }
    
    void registerAircraft(std::shared_ptr<Aircraft> aircraft) override {
        aircrafts_.push_back(aircraft);
        std::cout << "塔台: 注册航班 " << aircraft->getFlightId() << std::endl;
    }
};

// 演示代码
int main() {
    // 创建航空管制中心
    auto atc = std::make_shared<ConcreteATC>();
    
    // 创建飞机
    auto flight1 = std::make_shared<CommercialAircraft>("CA123", atc);
    auto flight2 = std::make_shared<CommercialAircraft>("UA456", atc);
    auto flight3 = std::make_shared<CommercialAircraft>("DL789", atc);
    
    // 注册飞机
    atc->registerAircraft(flight1);
    atc->registerAircraft(flight2);
    atc->registerAircraft(flight3);
    
    std::cout << "\n=== 航空管制演示 ===\n" << std::endl;
    
    // 飞机操作
    flight1->requestTakeoff();  // 应该成功
    flight1->notifyTakeoffComplete();
    
    flight2->requestTakeoff();  // 应该成功
    flight3->requestLanding();  // 应该被拒绝(跑道忙碌)
    
    flight2->notifyTakeoffComplete();
    flight3->requestLanding();  // 现在应该成功
    
    return 0;
}

3.3 案例三:UI组件交互系统

场景描述
设计一个用户界面,包含多个交互组件(按钮、文本框、复选框等),这些组件之间的行为相互影响,但组件之间不直接通信,通过中介者协调。

#include <iostream>
#include <string>
#include <unordered_map>
#include <memory>
#include <functional>

// 前向声明
class UIComponent;

/**
 * @brief UI中介者接口
 * 
 * 协调UI组件之间的交互行为
 */
class UIMediator {
public:
    virtual ~UIMediator() = default;
    
    /**
     * @brief 组件状态变化通知
     * 
     * @param component 发生变化的组件
     * @param event 事件类型
     */
    virtual void notify(std::shared_ptr<UIComponent> component, 
                       const std::string& event) = 0;
    
    /**
     * @brief 注册组件
     * 
     * @param id 组件ID
     * @param component 组件对象
     */
    virtual void registerComponent(const std::string& id, 
                                 std::shared_ptr<UIComponent> component) = 0;
};

/**
 * @brief UI组件抽象类
 */
class UIComponent {
protected:
    std::string id_;
    bool enabled_;
    std::shared_ptr<UIMediator> mediator_;

public:
    UIComponent(const std::string& id, std::shared_ptr<UIMediator> mediator)
        : id_(id), enabled_(true), mediator_(mediator) {}
    
    virtual ~UIComponent() = default;
    
    std::string getId() const { return id_; }
    bool isEnabled() const { return enabled_; }
    
    virtual void setEnabled(bool enabled) {
        enabled_ = enabled;
        std::cout << "组件 " << id_ << " " 
                  << (enabled ? "启用" : "禁用") << std::endl;
    }
    
    /**
     * @brief 触发组件行为
     */
    virtual void trigger() {
        if (enabled_) {
            std::cout << "组件 " << id_ << " 被触发" << std::endl;
            mediator_->notify(shared_from_this(), "triggered");
        }
    }
    
    /**
     * @brief 处理来自中介者的通知
     * 
     * @param event 事件类型
     * @param data 事件数据
     */
    virtual void handleEvent(const std::string& event, 
                           const std::string& data = "") = 0;
};

/**
 * @brief 按钮组件
 */
class Button : public UIComponent, public std::enable_shared_from_this<Button> {
public:
    Button(const std::string& id, std::shared_ptr<UIMediator> mediator)
        : UIComponent(id, mediator) {}
    
    void handleEvent(const std::string& event, 
                    const std::string& data = "") override {
        if (event == "disable_buttons") {
            setEnabled(false);
        } else if (event == "enable_buttons") {
            setEnabled(true);
        }
    }
};

/**
 * @brief 文本框组件
 */
class TextBox : public UIComponent, public std::enable_shared_from_this<TextBox> {
private:
    std::string text_;

public:
    TextBox(const std::string& id, std::shared_ptr<UIMediator> mediator)
        : UIComponent(id, mediator), text_("") {}
    
    void setText(const std::string& text) {
        text_ = text;
        std::cout << "文本框 " << id_ << " 内容设置为: " << text << std::endl;
        mediator_->notify(shared_from_this(), "text_changed");
    }
    
    std::string getText() const { return text_; }
    
    void handleEvent(const std::string& event, 
                    const std::string& data = "") override {
        if (event == "clear_text") {
            setText("");
        } else if (event == "disable_input") {
            setEnabled(false);
        }
    }
};

/**
 * @brief 复选框组件
 */
class CheckBox : public UIComponent, public std::enable_shared_from_this<CheckBox> {
private:
    bool checked_;

public:
    CheckBox(const std::string& id, std::shared_ptr<UIMediator> mediator)
        : UIComponent(id, mediator), checked_(false) {}
    
    void setChecked(bool checked) {
        checked_ = checked;
        std::cout << "复选框 " << id_ << " " 
                  << (checked ? "选中" : "取消选中") << std::endl;
        mediator_->notify(shared_from_this(), "state_changed");
    }
    
    bool isChecked() const { return checked_; }
    
    void trigger() override {
        if (enabled_) {
            setChecked(!checked_);
        }
    }
    
    void handleEvent(const std::string& event, 
                    const std::string& data = "") override {
        // 复选框对其他组件事件不敏感
    }
};

/**
 * @brief 具体UI中介者
 */
class ConcreteUIMediator : public UIMediator {
private:
    std::unordered_map<std::string, std::shared_ptr<UIComponent>> components_;

public:
    void notify(std::shared_ptr<UIComponent> component, 
               const std::string& event) override {
        std::string componentId = component->getId();
        
        if (componentId == "submit_btn" && event == "triggered") {
            // 提交按钮被点击:禁用所有按钮,清空文本框
            for (auto& pair : components_) {
                if (pair.first.find("btn") != std::string::npos) {
                    pair.second->handleEvent("disable_buttons");
                } else if (pair.first.find("textbox") != std::string::npos) {
                    pair.second->handleEvent("clear_text");
                }
            }
        } else if (componentId == "agree_checkbox" && event == "state_changed") {
            // 同意复选框状态变化:启用/禁用提交按钮
            auto checkbox = std::dynamic_pointer_cast<CheckBox>(component);
            if (checkbox) {
                auto submitBtn = components_["submit_btn"];
                if (submitBtn) {
                    submitBtn->setEnabled(checkbox->isChecked());
                }
            }
        } else if (componentId == "name_textbox" && event == "text_changed") {
            // 姓名文本框内容变化:检查是否可以启用提交按钮
            auto textbox = std::dynamic_pointer_cast<TextBox>(component);
            if (textbox) {
                auto agreeCheckbox = components_["agree_checkbox"];
                auto submitBtn = components_["submit_btn"];
                
                if (agreeCheckbox && submitBtn) {
                    bool agreed = std::dynamic_pointer_cast<CheckBox>(agreeCheckbox)->isChecked();
                    bool hasName = !textbox->getText().empty();
                    submitBtn->setEnabled(agreed && hasName);
                }
            }
        }
    }
    
    void registerComponent(const std::string& id, 
                         std::shared_ptr<UIComponent> component) override {
        components_[id] = component;
        std::cout << "注册UI组件: " << id << std::endl;
    }
};

// 演示代码
int main() {
    // 创建UI中介者
    auto mediator = std::make_shared<ConcreteUIMediator>();
    
    // 创建UI组件
    auto nameTextbox = std::make_shared<TextBox>("name_textbox", mediator);
    auto agreeCheckbox = std::make_shared<CheckBox>("agree_checkbox", mediator);
    auto submitButton = std::make_shared<Button>("submit_btn", mediator);
    
    // 注册组件
    mediator->registerComponent("name_textbox", nameTextbox);
    mediator->registerComponent("agree_checkbox", agreeCheckbox);
    mediator->registerComponent("submit_btn", submitButton);
    
    std::cout << "\n=== UI交互演示 ===\n" << std::endl;
    
    // 模拟用户交互
    std::cout << "1. 初始状态 - 提交按钮应该被禁用" << std::endl;
    std::cout << "提交按钮状态: " << (submitButton->isEnabled() ? "启用" : "禁用") << std::endl;
    
    std::cout << "\n2. 输入姓名 - 提交按钮仍然被禁用(未同意条款)" << std::endl;
    nameTextbox->setText("张三");
    std::cout << "提交按钮状态: " << (submitButton->isEnabled() ? "启用" : "禁用") << std::endl;
    
    std::cout << "\n3. 同意条款 - 提交按钮应该启用" << std::endl;
    agreeCheckbox->trigger();  // 选中复选框
    std::cout << "提交按钮状态: " << (submitButton->isEnabled() ? "启用" : "禁用") << std::endl;
    
    std::cout << "\n4. 点击提交按钮 - 所有按钮被禁用,文本框被清空" << std::endl;
    submitButton->trigger();
    
    return 0;
}

4. 编译与运行

4.1 Makefile范例

# 编译器设置
CXX := g++
CXXFLAGS := -std=c++17 -Wall -Wextra -O2
TARGET := mediator_demo
SRCS := chat_mediator.cpp aircraft_mediator.cpp ui_mediator.cpp

# 默认目标
all: $(TARGET)

# 链接目标文件
$(TARGET): $(SRCS:.cpp=.o)
	$(CXX) $(CXXFLAGS) -o $@ $^

# 编译源文件
%.o: %.cpp
	$(CXX) $(CXXFLAGS) -c $< -o $@

# 清理生成文件
clean:
	rm -f *.o $(TARGET)

# 运行演示
run: $(TARGET)
	./$(TARGET)

# 调试编译
debug: CXXFLAGS += -g -DDEBUG
debug: $(TARGET)

.PHONY: all clean run debug

4.2 编译方法

# 1. 基础编译
make

# 2. 调试模式编译
make debug

# 3. 单独编译聊天室案例
g++ -std=c++17 -o chat_demo chat_mediator.cpp

# 4. 清理编译文件
make clean

4.3 运行结果解读

聊天室系统输出示例

=== 聊天开始 ===

Alice 发送广播: 大家好!
=== 聊天室广播 === (Alice): 大家好!
Bob 收到来自 Alice 的消息: 大家好!
Charlie 收到来自 Alice 的消息: 大家好!

Alice 私聊 Bob: 嘿,Bob,有个秘密要告诉你
=== 私聊消息 === [Alice -> Bob]: 嘿,Bob,有个秘密要告诉你
Bob 收到来自 Alice 的消息: [私聊] 嘿,Bob,有个秘密要告诉你

结果分析

  • 消息通过中介者正确路由到目标用户
  • 广播消息发送给除发送者外的所有用户
  • 私聊消息只发送给指定用户
  • 系统消息(用户加入/离开)自动广播

5. 模式优势与局限性总结

5.1 优势对比

方面使用中介者模式前使用中介者模式后
耦合度对象间直接引用,网状耦合通过中介者通信,星状耦合
可维护性修改一个对象影响多个对象交互逻辑集中,易于维护
扩展性新增对象需要修改多个现有对象新增对象只需注册到中介者
复用性对象因相互引用难以单独复用对象可以独立复用

5.2 适用场景建议

推荐使用中介者模式

  • 🎯 对象间交互复杂且频繁
  • 🎯 需要集中管理对象间关系
  • 🎯 系统需要良好的扩展性和维护性

不推荐使用中介者模式

  • ⚠️ 对象间交互简单直接
  • ⚠️ 性能要求极高的场景
  • ⚠️ 中介者可能成为系统瓶颈

中介者模式通过引入协调层,成功地将复杂的网状交互转化为清晰的星状结构,是现代软件设计中解决对象通信复杂性的重要工具。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青草地溪水旁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值