设计模式-中介者模式

一、中介者模式核心概念解析

中介者模式是一种行为型设计模式 ,它的核心作用是:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互

你可以把它理解成生活中的「项目经理」:一个项目里有设计师、开发、测试多个角色,如果没有项目经理(中介者),每个人都要直接沟通(设计师找开发、开发找测试、测试找设计师),耦合度极高;有了项目经理后,所有人只需要和项目经理沟通,由项目经理统一协调,大大降低了角色间的直接依赖。

中介者模式的关键角色
  1. 抽象中介者(Mediator):定义中介者与同事对象之间交互的接口,通常包含注册同事对象、转发交互请求的方法。
  2. 具体中介者(ConcreteMediator):实现抽象中介者接口,持有所有同事对象的引用,负责具体的协调逻辑,处理同事对象的请求并转发给相关对象。
  3. 抽象同事类(Colleague):定义同事对象的通用接口,持有抽象中介者的引用,所有具体同事类都继承此类。
  4. 具体同事类(ConcreteColleague):实现抽象同事类接口,当需要与其他同事交互时,不直接调用其他同事,而是通过中介者转发请求。
中介者模式的核心优势
  • 降低对象间的耦合度:同事对象无需知道其他同事的具体实现,只依赖中介者。
  • 集中管理交互逻辑:所有对象间的交互都集中在中介者中,便于统一维护和扩展。
  • 符合「迪米特法则」(最少知道原则):每个对象只需要和中介者通信,减少不必要的依赖。

二、C++ 代码示例(聊天室场景)

下面以「多人聊天室」为例:聊天室里有多个用户(具体同事),用户发送消息时不直接发给其他用户,而是通过聊天室(具体中介者)转发给所有在线用户,这是中介者模式的典型应用。

完整代码

cpp

运行

cpp 复制代码
#include <iostream>
#include <string>
#include <vector>
#include <memory> // 智能指针,避免内存泄漏

// 前置声明:抽象同事类(用户),供抽象中介者使用
class Colleague;

// 1. 抽象中介者:定义聊天室的通用接口
class Mediator {
public:
    virtual ~Mediator() = default;
    // 注册用户到聊天室
    virtual void registerColleague(std::shared_ptr<Colleague> colleague) = 0;
    // 转发消息:由发送者发送,中介者转发给其他用户
    virtual void sendMessage(const std::string& message, std::shared_ptr<Colleague> sender) = 0;
};

// 2. 抽象同事类:定义用户的通用接口
class Colleague {
protected:
    std::shared_ptr<Mediator> mediator_; // 持有中介者引用
    std::string name_; // 用户名
public:
    Colleague(std::shared_ptr<Mediator> mediator, const std::string& name)
        : mediator_(mediator), name_(name) {}
    
    virtual ~Colleague() = default;
    
    // 获取用户名
    std::string getName() const { return name_; }
    
    // 发送消息(通过中介者)
    virtual void send(const std::string& message) = 0;
    
    // 接收消息(由中介者调用)
    virtual void receive(const std::string& message, const std::string& senderName) = 0;
};

// 3. 具体中介者:聊天室
class ChatRoomMediator : public Mediator {
private:
    std::vector<std::shared_ptr<Colleague>> colleagues_; // 存储所有在线用户
public:
    // 注册用户
    void registerColleague(std::shared_ptr<Colleague> colleague) override {
        colleagues_.push_back(colleague);
        std::cout << "【聊天室】用户 " << colleague->getName() << " 加入聊天室" << std::endl;
    }
    
    // 转发消息:给除发送者外的所有用户发消息
    void sendMessage(const std::string& message, std::shared_ptr<Colleague> sender) override {
        for (auto& colleague : colleagues_) {
            // 排除发送者自己
            if (colleague != sender) {
                colleague->receive(message, sender->getName());
            }
        }
    }
};

// 4. 具体同事类:普通用户
class User : public Colleague {
public:
    User(std::shared_ptr<Mediator> mediator, const std::string& name)
        : Colleague(mediator, name) {}
    
    // 发送消息:调用中介者的转发方法
    void send(const std::string& message) override {
        std::cout << "【" << name_ << "】发送消息:" << message << std::endl;
        mediator_->sendMessage(message, shared_from_this()); // 转发给中介者
    }
    
    // 接收消息:显示收到的消息
    void receive(const std::string& message, const std::string& senderName) override {
        std::cout << "【" << name_ << "】收到来自" << senderName << "的消息:" << message << std::endl;
    }
};

// 客户端代码
int main() {
    // 1. 创建聊天室(具体中介者)
    std::shared_ptr<Mediator> chatRoom = std::make_shared<ChatRoomMediator>();
    
    // 2. 创建用户(具体同事),并注册到聊天室
    std::shared_ptr<Colleague> user1 = std::make_shared<User>(chatRoom, "张三");
    std::shared_ptr<Colleague> user2 = std::make_shared<User>(chatRoom, "李四");
    std::shared_ptr<Colleague> user3 = std::make_shared<User>(chatRoom, "王五");
    
    chatRoom->registerColleague(user1);
    chatRoom->registerColleague(user2);
    chatRoom->registerColleague(user3);
    
    // 3. 用户发送消息(通过中介者转发)
    std::cout << "\n===== 聊天开始 =====" << std::endl;
    user1->send("大家好,我是张三!");
    std::cout << "---------------------" << std::endl;
    user2->send("张三你好,我是李四~");
    std::cout << "---------------------" << std::endl;
    user3->send("大家好,新人报道👋");
    
    return 0;
}
代码解释
  1. 抽象中介者(Mediator) :定义了registerColleague(注册用户)和sendMessage(转发消息)两个核心接口,是聊天室的通用规范。
  2. 具体中介者(ChatRoomMediator)
    • 持有所有在线用户的列表(colleagues_);
    • 实现registerColleague:将用户加入聊天室;
    • 实现sendMessage:遍历所有用户,把消息转发给除发送者外的其他用户(核心协调逻辑)。
  3. 抽象同事类(Colleague)
    • 持有中介者的引用(mediator_),确保所有用户都能访问聊天室;
    • 定义send(发送消息)和receive(接收消息)的接口,统一用户行为。
  4. 具体同事类(User)
    • 实现send方法:用户发送消息时,不直接调用其他用户,而是通过mediator_->sendMessage把消息交给中介者转发;
    • 实现receive方法:接收中介者转发的消息,并打印显示。
  5. 客户端代码
    • 创建聊天室和用户,将用户注册到聊天室;
    • 调用用户的send方法发送消息,所有交互由中介者协调,用户间无直接依赖。
运行结果

plaintext

cpp 复制代码
【聊天室】用户 张三 加入聊天室
【聊天室】用户 李四 加入聊天室
【聊天室】用户 王五 加入聊天室

===== 聊天开始 =====
【张三】发送消息:大家好,我是张三!
【李四】收到来自张三的消息:大家好,我是张三!
【王五】收到来自张三的消息:大家好,我是张三!
---------------------
【李四】发送消息:张三你好,我是李四~
【张三】收到来自李四的消息:张三你好,我是李四~
【王五】收到来自李四的消息:张三你好,我是李四~
---------------------
【王五】发送消息:大家好,新人报道👋
【张三】收到来自王五的消息:大家好,新人报道👋
【李四】收到来自王五的消息:大家好,新人报道👋

三、中介者模式的扩展思考(进阶补充)

1. 中介者模式的潜在问题
  • 中介者可能会「过度膨胀」:所有交互逻辑都集中在中介者中,当交互场景复杂时(比如聊天室支持私聊、禁言等),具体中介者类会变得非常庞大,难以维护。
  • 中介者成为「单点故障」:如果中介者出错,整个系统的交互都会受影响。
2. 优化方向
  • 拆分中介者:将复杂的交互逻辑拆分为多个细分中介者(比如私聊中介者、群聊中介者);
  • 结合其他模式:比如用工厂模式创建中介者,用观察者模式优化中介者与同事的消息通知。

总结

  1. 核心作用:中介者模式通过引入统一的中介对象,封装多个对象间的交互,降低对象间的直接耦合,让交互逻辑集中管理。
  2. 核心结构:抽象中介者(定义接口)→ 具体中介者(实现协调逻辑);抽象同事(持有中介者)→ 具体同事(通过中介者交互)。
  3. 适用场景:多个对象间存在复杂的交互关系(如聊天室、GUI 组件交互、分布式系统协调),且希望降低对象间耦合时。

这个模式的核心思想是「化繁为简」------ 把多对多的复杂交互,转化为同事与中介者之间的一对多交互,是解耦复杂系统的重要手段。

相关推荐
__万波__5 分钟前
二十三种设计模式(二十二)--策略模式
java·设计模式·策略模式
꧁Q༒ོγ꧂5 分钟前
C++ 入门完全指南(六)--指针与动态内存
开发语言·c++
永远不打烊6 分钟前
c++ 11 之 并发与多线程
c++
say_fall14 分钟前
C++ 类与对象易错点:初始化列表顺序 / 静态成员访问 / 隐式类型转换
android·java·开发语言·c++
ChoSeitaku40 分钟前
16.C++入门:list|手撕list|反向迭代器|与vector对比
c++·windows·list
Qhumaing1 小时前
C++学习:【PTA】数据结构 7-1 实验6-1(图-邻接矩阵)
c++·学习·算法
Overt0p1 小时前
抽奖系统(6)
java·spring boot·redis·设计模式·rabbitmq·状态模式
No0d1es1 小时前
2025年12月 GESP CCF编程能力等级认证C++一级真题
开发语言·c++·青少年编程·gesp·ccf
2301_773730311 小时前
系统编程—在线商城信息查询系统
c++·html
郝学胜-神的一滴1 小时前
深入理解Linux中的Try锁机制
linux·服务器·开发语言·c++·程序人生