17.C++设计模式-中介者模式

第一部分:模式基础详解

1. 模式概述

中介者模式(Mediator Pattern)是一种行为设计模式,通过引入一个中介对象来封装一组对象之间的交互。中介者使各对象不需要显式地相互引用,从而降低耦合度,并可以独立地改变它们之间的交互。

2. 核心角色

#mermaid-svg-QWs71ZgdqgRynD4g{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QWs71ZgdqgRynD4g .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QWs71ZgdqgRynD4g .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QWs71ZgdqgRynD4g .error-icon{fill:#552222;}#mermaid-svg-QWs71ZgdqgRynD4g .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QWs71ZgdqgRynD4g .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QWs71ZgdqgRynD4g .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QWs71ZgdqgRynD4g .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QWs71ZgdqgRynD4g .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QWs71ZgdqgRynD4g .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QWs71ZgdqgRynD4g .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QWs71ZgdqgRynD4g .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QWs71ZgdqgRynD4g .marker.cross{stroke:#333333;}#mermaid-svg-QWs71ZgdqgRynD4g svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QWs71ZgdqgRynD4g p{margin:0;}#mermaid-svg-QWs71ZgdqgRynD4g g.classGroup text{fill:#9370DB;stroke:none;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-QWs71ZgdqgRynD4g g.classGroup text .title{font-weight:bolder;}#mermaid-svg-QWs71ZgdqgRynD4g .cluster-label text{fill:#333;}#mermaid-svg-QWs71ZgdqgRynD4g .cluster-label span{color:#333;}#mermaid-svg-QWs71ZgdqgRynD4g .cluster-label span p{background-color:transparent;}#mermaid-svg-QWs71ZgdqgRynD4g .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QWs71ZgdqgRynD4g .cluster text{fill:#333;}#mermaid-svg-QWs71ZgdqgRynD4g .cluster span{color:#333;}#mermaid-svg-QWs71ZgdqgRynD4g .nodeLabel,#mermaid-svg-QWs71ZgdqgRynD4g .edgeLabel{color:#131300;}#mermaid-svg-QWs71ZgdqgRynD4g .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-QWs71ZgdqgRynD4g .label text{fill:#131300;}#mermaid-svg-QWs71ZgdqgRynD4g .labelBkg{background:#ECECFF;}#mermaid-svg-QWs71ZgdqgRynD4g .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-QWs71ZgdqgRynD4g .classTitle{font-weight:bolder;}#mermaid-svg-QWs71ZgdqgRynD4g .node rect,#mermaid-svg-QWs71ZgdqgRynD4g .node circle,#mermaid-svg-QWs71ZgdqgRynD4g .node ellipse,#mermaid-svg-QWs71ZgdqgRynD4g .node polygon,#mermaid-svg-QWs71ZgdqgRynD4g .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QWs71ZgdqgRynD4g .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-QWs71ZgdqgRynD4g g.clickable{cursor:pointer;}#mermaid-svg-QWs71ZgdqgRynD4g g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-QWs71ZgdqgRynD4g g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-QWs71ZgdqgRynD4g .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-QWs71ZgdqgRynD4g .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-QWs71ZgdqgRynD4g .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-QWs71ZgdqgRynD4g .dashed-line{stroke-dasharray:3;}#mermaid-svg-QWs71ZgdqgRynD4g .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-QWs71ZgdqgRynD4g #compositionStart,#mermaid-svg-QWs71ZgdqgRynD4g .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QWs71ZgdqgRynD4g #compositionEnd,#mermaid-svg-QWs71ZgdqgRynD4g .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QWs71ZgdqgRynD4g #dependencyStart,#mermaid-svg-QWs71ZgdqgRynD4g .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QWs71ZgdqgRynD4g #dependencyStart,#mermaid-svg-QWs71ZgdqgRynD4g .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QWs71ZgdqgRynD4g #extensionStart,#mermaid-svg-QWs71ZgdqgRynD4g .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QWs71ZgdqgRynD4g #extensionEnd,#mermaid-svg-QWs71ZgdqgRynD4g .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QWs71ZgdqgRynD4g #aggregationStart,#mermaid-svg-QWs71ZgdqgRynD4g .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QWs71ZgdqgRynD4g #aggregationEnd,#mermaid-svg-QWs71ZgdqgRynD4g .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QWs71ZgdqgRynD4g #lollipopStart,#mermaid-svg-QWs71ZgdqgRynD4g .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QWs71ZgdqgRynD4g #lollipopEnd,#mermaid-svg-QWs71ZgdqgRynD4g .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-QWs71ZgdqgRynD4g .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-QWs71ZgdqgRynD4g .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QWs71ZgdqgRynD4g .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QWs71ZgdqgRynD4g .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QWs71ZgdqgRynD4g :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} <<interface>>
Mediator
+notify(sender, event)
ConcreteMediator
-colleague1
-colleague2
+notify(sender, event)
<<abstract>>
Colleague
-mediator
+setMediator(mediator)
+send(event)
+receive(event)
ConcreteColleagueA
+receive(event)
ConcreteColleagueB
+receive(event)

3. 应用场景

  • 聊天室系统:用户通过聊天室发送和接收消息
  • 航空管制系统:塔台协调飞机起降
  • GUI组件交互:按钮、文本框、下拉框等组件的联动
  • 表单验证:多个表单字段的相互依赖验证
  • 工作流引擎:协调多个任务节点

4. C++代码示例

场景:智能家居控制系统

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

// 前向声明
class Colleague;

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

// 抽象同事类
class Colleague {
protected:
    std::shared_ptr<Mediator> mediator;
    std::string name;
    
public:
    Colleague(const std::string& n) : name(n) {}
    
    void setMediator(std::shared_ptr<Mediator> m) {
        mediator = m;
    }
    
    virtual void send(const std::string& event) {
        if (mediator) {
            mediator->notify(name, event);
        }
    }
    
    virtual void receive(const std::string& event) = 0;
    
    std::string getName() const { return name; }
    virtual ~Colleague() = default;
};

// 具体同事类:灯
class Light : public Colleague {
private:
    bool isOn = false;
    
public:
    Light(const std::string& n) : Colleague(n) {}
    
    void receive(const std::string& event) override {
        if (event == "turn_on") {
            isOn = true;
            std::cout << name << " 已打开" << std::endl;
        } else if (event == "turn_off") {
            isOn = false;
            std::cout << name << " 已关闭" << std::endl;
        }
    }
    
    bool getStatus() const { return isOn; }
};

// 具体同事类:空调
class AirConditioner : public Colleague {
private:
    int temperature = 22;
    
public:
    AirConditioner(const std::string& n) : Colleague(n) {}
    
    void receive(const std::string& event) override {
        if (event == "turn_on") {
            std::cout << name << " 已打开,当前温度:" << temperature << "°C" << std::endl;
        } else if (event == "turn_off") {
            std::cout << name << " 已关闭" << std::endl;
        } else if (event.substr(0, 12) == "set_temp_to_") {
            temperature = std::stoi(event.substr(12));
            std::cout << name << " 温度设置为:" << temperature << "°C" << std::endl;
        }
    }
};

// 具体同事类:智能音箱
class SmartSpeaker : public Colleague {
public:
    SmartSpeaker(const std::string& n) : Colleague(n) {}
    
    void receive(const std::string& event) override {
        if (event == "play_music") {
            std::cout << name << " 开始播放音乐" << std::endl;
        } else if (event == "stop_music") {
            std::cout << name << " 停止播放音乐" << std::endl;
        } else if (event == "weather_report") {
            std::cout << name << " 播报天气:晴天,25°C" << std::endl;
        }
    }
};

// 具体中介者:智能家居控制中心
class SmartHomeHub : public Mediator, public std::enable_shared_from_this<SmartHomeHub> {
private:
    std::vector<std::shared_ptr<Colleague>> devices;
    
public:
    void addDevice(std::shared_ptr<Colleague> device) {
        devices.push_back(device);
        device->setMediator(shared_from_this());
    }
    
    void notify(const std::string& sender, const std::string& event) override {
        std::cout << "\n[智能家居中心] 收到来自 " << sender << " 的事件: " << event << std::endl;
        
        if (event == "good_morning") {
            // 早安模式:开灯、设置空调温度、播放新闻
            for (auto& device : devices) {
                if (device->getName() == "客厅灯") {
                    device->receive("turn_on");
                } else if (device->getName() == "空调") {
                    device->receive("turn_on");
                    device->receive("set_temp_to_24");
                } else if (device->getName() == "智能音箱") {
                    device->receive("weather_report");
                }
            }
        } 
        else if (event == "good_night") {
            // 晚安模式:关灯、关空调、停止音乐
            for (auto& device : devices) {
                if (device->getName() == "客厅灯" || device->getName() == "卧室灯") {
                    device->receive("turn_off");
                } else if (device->getName() == "空调") {
                    device->receive("turn_off");
                } else if (device->getName() == "智能音箱") {
                    device->receive("stop_music");
                }
            }
        }
        else if (event == "leave_home") {
            // 离家模式:关闭所有设备
            for (auto& device : devices) {
                device->receive("turn_off");
            }
        }
        else if (event == "light_on") {
            // 特定设备控制
            for (auto& device : devices) {
                if (device->getName() == "客厅灯") {
                    device->receive("turn_on");
                }
            }
        }
    }
};

// 客户端代码
int main() {
    // 创建中介者
    auto hub = std::make_shared<SmartHomeHub>();
    
    // 创建设备
    auto livingLight = std::make_shared<Light>("客厅灯");
    auto bedroomLight = std::make_shared<Light>("卧室灯");
    auto ac = std::make_shared<AirConditioner>("空调");
    auto speaker = std::make_shared<SmartSpeaker>("智能音箱");
    
    // 注册设备到中介者
    hub->addDevice(livingLight);
    hub->addDevice(bedroomLight);
    hub->addDevice(ac);
    hub->addDevice(speaker);
    
    // 设备通过中介者通信
    std::cout << "=== 早安模式 ===" << std::endl;
    speaker->send("good_morning");
    
    std::cout << "\n=== 离家模式 ===" << std::endl;
    speaker->send("leave_home");
    
    std::cout << "\n=== 单独控制灯光 ===" << std::endl;
    livingLight->send("light_on");
    
    return 0;
}

5. 交互流程图

空调 客厅灯 智能家居中心 智能音箱 空调 客厅灯 智能家居中心 智能音箱 #mermaid-svg-QgRex9waIyeXusCG{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QgRex9waIyeXusCG .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QgRex9waIyeXusCG .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QgRex9waIyeXusCG .error-icon{fill:#552222;}#mermaid-svg-QgRex9waIyeXusCG .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QgRex9waIyeXusCG .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QgRex9waIyeXusCG .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QgRex9waIyeXusCG .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QgRex9waIyeXusCG .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QgRex9waIyeXusCG .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QgRex9waIyeXusCG .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QgRex9waIyeXusCG .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QgRex9waIyeXusCG .marker.cross{stroke:#333333;}#mermaid-svg-QgRex9waIyeXusCG svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QgRex9waIyeXusCG p{margin:0;}#mermaid-svg-QgRex9waIyeXusCG .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-QgRex9waIyeXusCG text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-QgRex9waIyeXusCG .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-QgRex9waIyeXusCG .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-QgRex9waIyeXusCG .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-QgRex9waIyeXusCG .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-QgRex9waIyeXusCG #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-QgRex9waIyeXusCG .sequenceNumber{fill:white;}#mermaid-svg-QgRex9waIyeXusCG #sequencenumber{fill:#333;}#mermaid-svg-QgRex9waIyeXusCG #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-QgRex9waIyeXusCG .messageText{fill:#333;stroke:none;}#mermaid-svg-QgRex9waIyeXusCG .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-QgRex9waIyeXusCG .labelText,#mermaid-svg-QgRex9waIyeXusCG .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-QgRex9waIyeXusCG .loopText,#mermaid-svg-QgRex9waIyeXusCG .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-QgRex9waIyeXusCG .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-QgRex9waIyeXusCG .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-QgRex9waIyeXusCG .noteText,#mermaid-svg-QgRex9waIyeXusCG .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-QgRex9waIyeXusCG .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-QgRex9waIyeXusCG .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-QgRex9waIyeXusCG .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-QgRex9waIyeXusCG .actorPopupMenu{position:absolute;}#mermaid-svg-QgRex9waIyeXusCG .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-QgRex9waIyeXusCG .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-QgRex9waIyeXusCG .actor-man circle,#mermaid-svg-QgRex9waIyeXusCG line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-QgRex9waIyeXusCG :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 协调完成所有操作 send("good_morning")receive("turn_on")执行完成receive("turn_on")receive("set_temp_to_24")执行完成

6. 优缺点分析

优点:

  • ✅ 降低对象间耦合,提高可维护性
  • ✅ 集中控制交互逻辑,便于修改
  • ✅ 符合迪米特法则(最少知识原则)
  • ✅ 提高组件复用性

缺点:

  • ❌ 中介者可能变得庞大复杂(上帝对象)
  • ❌ 增加系统复杂度(需要额外的中介者对象)
  • ❌ 调试困难(交互集中在中介者)

7. 与其他模式对比

模式 适用场景 复杂度
中介者 多对象网状交互
观察者 一对多依赖通知
外观 简化复杂子系统接口

第二部分:核心思想思维深度讲解

1. 思维的本质转变

中介者模式最核心的思维转变是:从"对象知道对象"到"对象只知中介"
#mermaid-svg-bwJidQl3TMNBeMCq{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-bwJidQl3TMNBeMCq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-bwJidQl3TMNBeMCq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-bwJidQl3TMNBeMCq .error-icon{fill:#552222;}#mermaid-svg-bwJidQl3TMNBeMCq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-bwJidQl3TMNBeMCq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-bwJidQl3TMNBeMCq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-bwJidQl3TMNBeMCq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-bwJidQl3TMNBeMCq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-bwJidQl3TMNBeMCq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-bwJidQl3TMNBeMCq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-bwJidQl3TMNBeMCq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-bwJidQl3TMNBeMCq .marker.cross{stroke:#333333;}#mermaid-svg-bwJidQl3TMNBeMCq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-bwJidQl3TMNBeMCq p{margin:0;}#mermaid-svg-bwJidQl3TMNBeMCq .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-bwJidQl3TMNBeMCq .cluster-label text{fill:#333;}#mermaid-svg-bwJidQl3TMNBeMCq .cluster-label span{color:#333;}#mermaid-svg-bwJidQl3TMNBeMCq .cluster-label span p{background-color:transparent;}#mermaid-svg-bwJidQl3TMNBeMCq .label text,#mermaid-svg-bwJidQl3TMNBeMCq span{fill:#333;color:#333;}#mermaid-svg-bwJidQl3TMNBeMCq .node rect,#mermaid-svg-bwJidQl3TMNBeMCq .node circle,#mermaid-svg-bwJidQl3TMNBeMCq .node ellipse,#mermaid-svg-bwJidQl3TMNBeMCq .node polygon,#mermaid-svg-bwJidQl3TMNBeMCq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-bwJidQl3TMNBeMCq .rough-node .label text,#mermaid-svg-bwJidQl3TMNBeMCq .node .label text,#mermaid-svg-bwJidQl3TMNBeMCq .image-shape .label,#mermaid-svg-bwJidQl3TMNBeMCq .icon-shape .label{text-anchor:middle;}#mermaid-svg-bwJidQl3TMNBeMCq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-bwJidQl3TMNBeMCq .rough-node .label,#mermaid-svg-bwJidQl3TMNBeMCq .node .label,#mermaid-svg-bwJidQl3TMNBeMCq .image-shape .label,#mermaid-svg-bwJidQl3TMNBeMCq .icon-shape .label{text-align:center;}#mermaid-svg-bwJidQl3TMNBeMCq .node.clickable{cursor:pointer;}#mermaid-svg-bwJidQl3TMNBeMCq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-bwJidQl3TMNBeMCq .arrowheadPath{fill:#333333;}#mermaid-svg-bwJidQl3TMNBeMCq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-bwJidQl3TMNBeMCq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-bwJidQl3TMNBeMCq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bwJidQl3TMNBeMCq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-bwJidQl3TMNBeMCq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bwJidQl3TMNBeMCq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-bwJidQl3TMNBeMCq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-bwJidQl3TMNBeMCq .cluster text{fill:#333;}#mermaid-svg-bwJidQl3TMNBeMCq .cluster span{color:#333;}#mermaid-svg-bwJidQl3TMNBeMCq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-bwJidQl3TMNBeMCq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-bwJidQl3TMNBeMCq rect.text{fill:none;stroke-width:0;}#mermaid-svg-bwJidQl3TMNBeMCq .icon-shape,#mermaid-svg-bwJidQl3TMNBeMCq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bwJidQl3TMNBeMCq .icon-shape p,#mermaid-svg-bwJidQl3TMNBeMCq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-bwJidQl3TMNBeMCq .icon-shape .label rect,#mermaid-svg-bwJidQl3TMNBeMCq .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bwJidQl3TMNBeMCq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-bwJidQl3TMNBeMCq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-bwJidQl3TMNBeMCq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 中介者模式(星型结构)
对象A
中介者
对象B
对象C
对象D
传统网状交互(高耦合)
对象A
对象B
对象C
对象D

2. 四个关键思维转变

思维一:从"知道太多"到"只知必要"

cpp 复制代码
// ❌ 坏味道:对象知道太多其他对象
class BadLight {
    AirConditioner* ac;
    Speaker* speaker;
    Curtain* curtain;
    
    void morningMode() {
        ac->turnOn(24);
        speaker->play("news");
        curtain->open();
        this->turnOn();
    }
};

// ✅ 中介者思维:只知道中介者
class GoodLight {
    Mediator* mediator;  // 只需要知道这一个
    
    void morningMode() {
        mediator->notify("light", "morning_mode");
    }
};

思维二:从"我控制别人"到"我只通知变化"

cpp 复制代码
// ❌ 命令式思维:主动控制别人
class BadUserInterface {
    TextBox* nameBox;
    TextBox* emailBox;
    Button* submitBtn;
    
    void onNameChanged() {
        if(nameBox->getText().length() > 0) {
            emailBox->enable();
        }
        if(nameBox->getText().length() > 0 && 
           emailBox->getText().contains("@")) {
            submitBtn->enable();
        }
    }
};

// ✅ 声明式思维:只通知状态变化
class GoodUserInterface {
    Mediator* mediator;
    
    void onNameChanged() {
        mediator->notify("nameBox", "text_changed");
    }
};

思维三:从"硬编码路径"到"可配置策略"

#mermaid-svg-CVHJyyF97mSzzbJk{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-CVHJyyF97mSzzbJk .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-CVHJyyF97mSzzbJk .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-CVHJyyF97mSzzbJk .error-icon{fill:#552222;}#mermaid-svg-CVHJyyF97mSzzbJk .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CVHJyyF97mSzzbJk .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-CVHJyyF97mSzzbJk .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CVHJyyF97mSzzbJk .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CVHJyyF97mSzzbJk .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-CVHJyyF97mSzzbJk .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CVHJyyF97mSzzbJk .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CVHJyyF97mSzzbJk .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CVHJyyF97mSzzbJk .marker.cross{stroke:#333333;}#mermaid-svg-CVHJyyF97mSzzbJk svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CVHJyyF97mSzzbJk p{margin:0;}#mermaid-svg-CVHJyyF97mSzzbJk .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-CVHJyyF97mSzzbJk .cluster-label text{fill:#333;}#mermaid-svg-CVHJyyF97mSzzbJk .cluster-label span{color:#333;}#mermaid-svg-CVHJyyF97mSzzbJk .cluster-label span p{background-color:transparent;}#mermaid-svg-CVHJyyF97mSzzbJk .label text,#mermaid-svg-CVHJyyF97mSzzbJk span{fill:#333;color:#333;}#mermaid-svg-CVHJyyF97mSzzbJk .node rect,#mermaid-svg-CVHJyyF97mSzzbJk .node circle,#mermaid-svg-CVHJyyF97mSzzbJk .node ellipse,#mermaid-svg-CVHJyyF97mSzzbJk .node polygon,#mermaid-svg-CVHJyyF97mSzzbJk .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CVHJyyF97mSzzbJk .rough-node .label text,#mermaid-svg-CVHJyyF97mSzzbJk .node .label text,#mermaid-svg-CVHJyyF97mSzzbJk .image-shape .label,#mermaid-svg-CVHJyyF97mSzzbJk .icon-shape .label{text-anchor:middle;}#mermaid-svg-CVHJyyF97mSzzbJk .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-CVHJyyF97mSzzbJk .rough-node .label,#mermaid-svg-CVHJyyF97mSzzbJk .node .label,#mermaid-svg-CVHJyyF97mSzzbJk .image-shape .label,#mermaid-svg-CVHJyyF97mSzzbJk .icon-shape .label{text-align:center;}#mermaid-svg-CVHJyyF97mSzzbJk .node.clickable{cursor:pointer;}#mermaid-svg-CVHJyyF97mSzzbJk .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-CVHJyyF97mSzzbJk .arrowheadPath{fill:#333333;}#mermaid-svg-CVHJyyF97mSzzbJk .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-CVHJyyF97mSzzbJk .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-CVHJyyF97mSzzbJk .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CVHJyyF97mSzzbJk .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-CVHJyyF97mSzzbJk .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CVHJyyF97mSzzbJk .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-CVHJyyF97mSzzbJk .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-CVHJyyF97mSzzbJk .cluster text{fill:#333;}#mermaid-svg-CVHJyyF97mSzzbJk .cluster span{color:#333;}#mermaid-svg-CVHJyyF97mSzzbJk div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-CVHJyyF97mSzzbJk .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-CVHJyyF97mSzzbJk rect.text{fill:none;stroke-width:0;}#mermaid-svg-CVHJyyF97mSzzbJk .icon-shape,#mermaid-svg-CVHJyyF97mSzzbJk .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CVHJyyF97mSzzbJk .icon-shape p,#mermaid-svg-CVHJyyF97mSzzbJk .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-CVHJyyF97mSzzbJk .icon-shape .label rect,#mermaid-svg-CVHJyyF97mSzzbJk .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CVHJyyF97mSzzbJk .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-CVHJyyF97mSzzbJk .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-CVHJyyF97mSzzbJk :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 可配置交互
统一接口
策略1
策略2
策略3
对象A
中介者配置中心
对象B
对象C
对象D
硬编码交互
直接调用
直接调用
对象A
对象B
对象C

思维四:从"点对点通信"到"事件驱动协作"

cpp 复制代码
// 事件驱动的协作思维
class EventDrivenMediator : public Mediator {
    map<string, vector<function<void()>>> eventHandlers;
    
public:
    void registerHandler(string event, function<void()> handler) {
        eventHandlers[event].push_back(handler);
    }
    
    void notify(string sender, string event) override {
        // 事件驱动的协作:谁关心谁响应
        for(auto& handler : eventHandlers[event]) {
            handler();  // 多对多的协作,但彼此不知道
        }
    }
};

3. 深层哲学思想

3.1 解耦的极致:依赖倒置的应用

cpp 复制代码
// 依赖倒置:都依赖抽象的中介者
class Colleague {
    Mediator* mediator;  // 依赖抽象,不依赖具体
};

// 具体交互策略可以自由变化
class FlexibleMediator : public Mediator {
    // 交互逻辑完全可配置,不影响同事类
    map<pair<string, string>, vector<string>> rules;
};

3.2 控制反转的体现

中介者 同事对象 中介者 同事对象 #mermaid-svg-KFNek4vWOp9sehrQ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-KFNek4vWOp9sehrQ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-KFNek4vWOp9sehrQ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-KFNek4vWOp9sehrQ .error-icon{fill:#552222;}#mermaid-svg-KFNek4vWOp9sehrQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-KFNek4vWOp9sehrQ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-KFNek4vWOp9sehrQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-KFNek4vWOp9sehrQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-KFNek4vWOp9sehrQ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-KFNek4vWOp9sehrQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-KFNek4vWOp9sehrQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-KFNek4vWOp9sehrQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-KFNek4vWOp9sehrQ .marker.cross{stroke:#333333;}#mermaid-svg-KFNek4vWOp9sehrQ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-KFNek4vWOp9sehrQ p{margin:0;}#mermaid-svg-KFNek4vWOp9sehrQ .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-KFNek4vWOp9sehrQ text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-KFNek4vWOp9sehrQ .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-KFNek4vWOp9sehrQ .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-KFNek4vWOp9sehrQ .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-KFNek4vWOp9sehrQ .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-KFNek4vWOp9sehrQ #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-KFNek4vWOp9sehrQ .sequenceNumber{fill:white;}#mermaid-svg-KFNek4vWOp9sehrQ #sequencenumber{fill:#333;}#mermaid-svg-KFNek4vWOp9sehrQ #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-KFNek4vWOp9sehrQ .messageText{fill:#333;stroke:none;}#mermaid-svg-KFNek4vWOp9sehrQ .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-KFNek4vWOp9sehrQ .labelText,#mermaid-svg-KFNek4vWOp9sehrQ .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-KFNek4vWOp9sehrQ .loopText,#mermaid-svg-KFNek4vWOp9sehrQ .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-KFNek4vWOp9sehrQ .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-KFNek4vWOp9sehrQ .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-KFNek4vWOp9sehrQ .noteText,#mermaid-svg-KFNek4vWOp9sehrQ .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-KFNek4vWOp9sehrQ .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-KFNek4vWOp9sehrQ .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-KFNek4vWOp9sehrQ .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-KFNek4vWOp9sehrQ .actorPopupMenu{position:absolute;}#mermaid-svg-KFNek4vWOp9sehrQ .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-KFNek4vWOp9sehrQ .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-KFNek4vWOp9sehrQ .actor-man circle,#mermaid-svg-KFNek4vWOp9sehrQ line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-KFNek4vWOp9sehrQ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 传统控制流:C控制M 控制反转:M控制C 执行这个、执行那个你需要做什么我完成了现在你需要做什么

3.3 关注点分离

cpp 复制代码
// 交互逻辑与业务逻辑分离
class BusinessLogic {  // 只关心自己的业务
    void doWork() { /* 业务逻辑 */ }
};

class InteractionLogic {  // 中介者关心交互
    void coordinate() {
        // 协调多个 BusinessLogic 对象
    }
};

4. 高级思维模式

模式一:中介者作为协议

cpp 复制代码
// 将交互协议封装在中介者中
class ProtocolMediator {
    // 就像网络协议一样,定义交互规则
    enum ProtocolState {
        HANDSHAKE,
        DATA_TRANSFER,
        TERMINATION
    };
    
    ProtocolState state;
    
    void handleMessage(Message msg) {
        switch(state) {
            case HANDSHAKE: /* 握手逻辑 */
            case DATA_TRANSFER: /* 数据传输 */
            case TERMINATION: /* 终止逻辑 */
        }
    }
};

模式二:中介者作为路由器

cpp 复制代码
// 智能路由中介者
class RouterMediator {
    map<string, string> routingTable;  // 消息路由表
    
    void route(string from, string message) {
        string to = routingTable[message];
        // 根据消息内容智能路由到目标对象
    }
};

5. 思维的延伸应用

这个思维模式不仅适用于编程,也适用于:

  1. 组织管理:部门经理作为中介者协调员工
  2. 交通系统:交通灯作为中介者协调车辆
  3. 金融交易:交易所作为中介者匹配买卖订单

#mermaid-svg-OCjOGkFFqCP2vynq{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-OCjOGkFFqCP2vynq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-OCjOGkFFqCP2vynq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-OCjOGkFFqCP2vynq .error-icon{fill:#552222;}#mermaid-svg-OCjOGkFFqCP2vynq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-OCjOGkFFqCP2vynq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-OCjOGkFFqCP2vynq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-OCjOGkFFqCP2vynq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-OCjOGkFFqCP2vynq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-OCjOGkFFqCP2vynq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-OCjOGkFFqCP2vynq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-OCjOGkFFqCP2vynq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-OCjOGkFFqCP2vynq .marker.cross{stroke:#333333;}#mermaid-svg-OCjOGkFFqCP2vynq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-OCjOGkFFqCP2vynq p{margin:0;}#mermaid-svg-OCjOGkFFqCP2vynq .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-OCjOGkFFqCP2vynq .cluster-label text{fill:#333;}#mermaid-svg-OCjOGkFFqCP2vynq .cluster-label span{color:#333;}#mermaid-svg-OCjOGkFFqCP2vynq .cluster-label span p{background-color:transparent;}#mermaid-svg-OCjOGkFFqCP2vynq .label text,#mermaid-svg-OCjOGkFFqCP2vynq span{fill:#333;color:#333;}#mermaid-svg-OCjOGkFFqCP2vynq .node rect,#mermaid-svg-OCjOGkFFqCP2vynq .node circle,#mermaid-svg-OCjOGkFFqCP2vynq .node ellipse,#mermaid-svg-OCjOGkFFqCP2vynq .node polygon,#mermaid-svg-OCjOGkFFqCP2vynq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-OCjOGkFFqCP2vynq .rough-node .label text,#mermaid-svg-OCjOGkFFqCP2vynq .node .label text,#mermaid-svg-OCjOGkFFqCP2vynq .image-shape .label,#mermaid-svg-OCjOGkFFqCP2vynq .icon-shape .label{text-anchor:middle;}#mermaid-svg-OCjOGkFFqCP2vynq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-OCjOGkFFqCP2vynq .rough-node .label,#mermaid-svg-OCjOGkFFqCP2vynq .node .label,#mermaid-svg-OCjOGkFFqCP2vynq .image-shape .label,#mermaid-svg-OCjOGkFFqCP2vynq .icon-shape .label{text-align:center;}#mermaid-svg-OCjOGkFFqCP2vynq .node.clickable{cursor:pointer;}#mermaid-svg-OCjOGkFFqCP2vynq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-OCjOGkFFqCP2vynq .arrowheadPath{fill:#333333;}#mermaid-svg-OCjOGkFFqCP2vynq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-OCjOGkFFqCP2vynq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-OCjOGkFFqCP2vynq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OCjOGkFFqCP2vynq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-OCjOGkFFqCP2vynq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OCjOGkFFqCP2vynq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-OCjOGkFFqCP2vynq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-OCjOGkFFqCP2vynq .cluster text{fill:#333;}#mermaid-svg-OCjOGkFFqCP2vynq .cluster span{color:#333;}#mermaid-svg-OCjOGkFFqCP2vynq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-OCjOGkFFqCP2vynq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-OCjOGkFFqCP2vynq rect.text{fill:none;stroke-width:0;}#mermaid-svg-OCjOGkFFqCP2vynq .icon-shape,#mermaid-svg-OCjOGkFFqCP2vynq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OCjOGkFFqCP2vynq .icon-shape p,#mermaid-svg-OCjOGkFFqCP2vynq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-OCjOGkFFqCP2vynq .icon-shape .label rect,#mermaid-svg-OCjOGkFFqCP2vynq .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OCjOGkFFqCP2vynq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-OCjOGkFFqCP2vynq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-OCjOGkFFqCP2vynq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 思维应用类比
编程思维

中介者模式
组织管理

部门经理协调
交通系统

交通灯控制
金融领域

交易所匹配
通信系统

交换机路由

6. 思维检查清单

使用中介者模式时,问自己:

  • 对象是否知道太多其他对象的细节?
  • 修改一个对象是否需要修改多个其他对象?
  • 对象的交互逻辑是否难以理解和维护?
  • 是否可以在不修改对象本身的情况下改变交互方式?
  • 是否可以将交互逻辑提取出来独立变化?

7. 思维陷阱提醒

⚠️ 不要把中介者变成"上帝对象"

cpp 复制代码
// 坏味道:什么都知道的中介者
class GodMediator {
    Light* light;
    AC* ac;
    TV* tv;
    Speaker* speaker;
    Curtain* curtain;
    // ... 100+ 个成员变量
    
    void doEverything() {
        // 包含所有业务逻辑
    }
};

正确思维:应该拆分为多个专门的中介者

cpp 复制代码
// 好味道:职责单一的中介者
class LightingMediator { /* 只管理灯光 */ };
class ClimateMediator { /* 只管理温控 */ };
class EntertainmentMediator { /* 只管理娱乐 */ };

第三部分:总结与最佳实践

核心总结

中介者模式的本质思维:

  • 减少认知负担:每个对象只需要认识中介者
  • 改变控制流向:从对象间相互控制到中介者集中控制
  • 提取变化点:将易变的交互逻辑封装在中介者中
  • 面向接口协作:所有交互都通过抽象中介者接口

核心价值: 通过增加一个间接层,将网状复杂度转换为星型简洁度,从而让系统更容易理解、维护和扩展。

最佳实践建议

  1. 适用判断:当系统中存在多对多的复杂交互关系时考虑使用
  2. 避免上帝对象:将复杂的中介者拆分为多个专门的中介者
  3. 结合工厂模式:使用工厂创建同事对象,降低耦合
  4. 异步处理:对于耗时操作,考虑使用异步消息队列
  5. 命名规范 :中介者命名应体现其协调职责(如 XxxCoordinatorXxxHub

这个模式在实际开发中非常实用,特别是处理复杂UI组件交互、工作流引擎、智能家居控制等场景。