当前位置: 首页 > article >正文

C++实现设计模式---中介者模式 (Mediator)

中介者模式 (Mediator)

中介者模式 是一种行为型设计模式,它用一个中介对象来封装一组对象之间的交互。中介者通过协调多个对象之间的通信,避免对象之间的直接依赖,从而实现对象之间的松耦合。


意图

  • 通过引入一个中介者对象,减少对象之间的直接依赖,从而降低耦合性。
  • 中介者负责管理和协调对象之间的通信。

使用场景

  1. 对象之间的交互变得复杂
    • 如果对象之间存在大量的直接引用和交互,可以使用中介者模式减少耦合。
  2. 希望解耦多个对象
    • 通过中介者,避免对象之间的直接依赖。
  3. 需要集中控制交互
    • 需要通过一个中心对象协调和控制所有对象的行为。

参与者角色

  1. 中介者接口 (Mediator)
    • 定义对象之间通信的接口。
  2. 具体中介者 (ConcreteMediator)
    • 实现中介者接口,负责具体的通信和协调。
  3. 同事类 (Colleague)
    • 定义与中介者通信的接口,所有同事类通过中介者进行通信。
  4. 具体同事类 (ConcreteColleague)
    • 实现同事类的行为,与中介者进行交互。

示例代码

以下代码展示了中介者模式的实现,模拟一个聊天室中的用户通过中介者进行通信的场景。

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

// 前置声明中介者
class Mediator;

// 同事类接口
class Colleague {
protected:
    Mediator* mediator; // 中介者指针
    std::string name;   // 同事名称

public:
    Colleague(Mediator* mediator, std::string name) : mediator(mediator), name(std::move(name)) {}
    virtual ~Colleague() = default;

    // 接收消息
    virtual void receiveMessage(const std::string& sender, const std::string& message) = 0;

    // 发送消息
    virtual void sendMessage(const std::string& message) = 0;

    std::string getName() const {
        return name;
    }
};

// 中介者接口
class Mediator {
public:
    virtual ~Mediator() = default;

    // 注册同事
    virtual void addColleague(std::shared_ptr<Colleague> colleague) = 0;

    // 转发消息
    virtual void relayMessage(const std::string& sender, const std::string& message) = 0;
};

// 具体中介者
class ChatMediator : public Mediator {
private:
    std::vector<std::shared_ptr<Colleague>> colleagues; // 同事列表

public:
    void addColleague(std::shared_ptr<Colleague> colleague) override {
        colleagues.push_back(std::move(colleague));
    }

    void relayMessage(const std::string& sender, const std::string& message) override {
        for (const auto& colleague : colleagues) {
            if (colleague->getName() != sender) {
                colleague->receiveMessage(sender, message); // 转发消息给其他同事
            }
        }
    }
};

// 具体同事类
class User : public Colleague {
public:
    User(Mediator* mediator, std::string name) : Colleague(mediator, std::move(name)) {}

    void receiveMessage(const std::string& sender, const std::string& message) override {
        std::cout << name << " 收到来自 " << sender << " 的消息: " << message << "
";
    }

    void sendMessage(const std::string& message) override {
        std::cout << name << " 发送消息: " << message << "
";
        mediator->relayMessage(name, message); // 通过中介者发送消息
    }
};

// 客户端代码
int main() {
    // 创建中介者
    auto chatMediator = std::make_shared<ChatMediator>();

    // 创建用户
    auto user1 = std::make_shared<User>(chatMediator.get(), "Alice");
    auto user2 = std::make_shared<User>(chatMediator.get(), "Bob");
    auto user3 = std::make_shared<User>(chatMediator.get(), "Charlie");

    // 注册用户到中介者
    chatMediator->addColleague(user1);
    chatMediator->addColleague(user2);
    chatMediator->addColleague(user3);

    // 用户发送消息
    user1->sendMessage("大家好!");
    user2->sendMessage("你好,Alice!");
    user3->sendMessage("欢迎加入聊天室!");

    return 0;
}

代码解析

1. 中介者接口 (Mediator)
  • 定义了对象之间通信的接口。
  • 包含方法 addColleague 用于注册同事对象,relayMessage 用于转发消息。
class Mediator {
public:
    virtual ~Mediator() = default;
    virtual void addColleague(std::shared_ptr<Colleague> colleague) = 0;
    virtual void relayMessage(const std::string& sender, const std::string& message) = 0;
};
2. 具体中介者 (ChatMediator)
  • 实现中介者接口,负责管理同事对象并转发消息。
class ChatMediator : public Mediator {
private:
    std::vector<std::shared_ptr<Colleague>> colleagues;
public:
    void addColleague(std::shared_ptr<Colleague> colleague) override {
        colleagues.push_back(std::move(colleague));
    }

    void relayMessage(const std::string& sender, const std::string& message) override {
        for (const auto& colleague : colleagues) {
            if (colleague->getName() != sender) {
                colleague->receiveMessage(sender, message);
            }
        }
    }
};
3. 同事类接口 (Colleague)
  • 定义与中介者通信的接口。
  • 包含方法 sendMessagereceiveMessage
class Colleague {
protected:
    Mediator* mediator;
    std::string name;
public:
    Colleague(Mediator* mediator, std::string name) : mediator(mediator), name(std::move(name)) {}
    virtual ~Colleague() = default;
    virtual void receiveMessage(const std::string& sender, const std::string& message) = 0;
    virtual void sendMessage(const std::string& message) = 0;
    std::string getName() const { return name; }
};
4. 具体同事类 (User)
  • 实现同事类的行为,与中介者进行交互。
class User : public Colleague {
public:
    User(Mediator* mediator, std::string name) : Colleague(mediator, std::move(name)) {}
    void receiveMessage(const std::string& sender, const std::string& message) override {
        std::cout << name << " 收到来自 " << sender << " 的消息: " << message << "
";
    }
    void sendMessage(const std::string& message) override {
        std::cout << name << " 发送消息: " << message << "
";
        mediator->relayMessage(name, message);
    }
};
5. 客户端代码
  • 客户端创建中介者和同事对象,并通过中介者实现对象之间的通信。

优缺点

优点
  1. 降低耦合
    • 同事对象之间无需直接引用,通过中介者完成通信。
  2. 集中控制
    • 通过中介者,可以集中管理和控制对象的交互。
  3. 灵活扩展
    • 可以通过扩展中介者的功能,改变对象间的交互逻辑。
缺点
  1. 中介者复杂性增加
    • 随着对象交互的增加,中介者可能变得复杂且难以维护。
  2. 单点故障
    • 中介者是交互的核心,其故障会影响整个系统。

适用场景

  1. 对象间的交互复杂
    • 希望通过引入中介者降低对象间的直接依赖。
  2. 需要集中控制交互逻辑
    • 希望通过中介者管理对象之间的通信。
  3. 希望解耦多个对象
    • 通过中介者实现对象之间的松耦合。

总结

中介者模式通过引入中介者对象,降低了对象之间的耦合性,同时集中管理了交互逻辑。它特别适用于对象间交互复杂且需要统一管理的场景。


http://www.kler.cn/a/508373.html

相关文章:

  • [Qt]常用控件介绍-多元素控件-QListWidget、QTableWidget、QQTreeWidget
  • 如何将数据库字符集改为中文,让今后所有的数据库都支持中文
  • Vue项目搭建教程超详细
  • IM聊天学习资源
  • 【数据库初阶】MySQL中表的约束(上)
  • 将Docker运行中的容器保存为镜像并导出导入
  • 【机器学习:三十三(一)、支持向量机】
  • YOLOv11改进,YOLOv11检测头融合RFAConv卷积,并添加小目标检测层(四头检测),适合目标检测、分割等任务
  • RV1126+FFMPEG推流项目(7)AI音频模块编码流程
  • 游戏引擎学习第80天
  • VTK知识学习(36)-图像平滑
  • 【spark源码修改】hive3.1.3 spark3.5.4编译,需要修改源码,最终编译成功
  • 全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之一维数组(应用技巧)
  • linux 国产化命令
  • 算法随笔_10: 供暖器
  • Linux网络 TCP socket
  • 一体机cell服务器更换内存步骤
  • java 小红书源码 1:1还原 uniapp
  • 小识MySQL中的OLTP和OLAP
  • 全类别机器人传感器模块推荐
  • RK3568笔记七十五:FFMPEG交叉编译
  • Rnote:Star 8.6k,github上的宝藏项目,手绘与手写画图笔记,用它画图做笔记超丝滑,值得尝试!
  • 如何在 ASP.NET Core 中实现速率限制?
  • [JavaScript] 变量与数据类型:从基础到进阶
  • C++第十五讲:异常
  • 春秋杯-WEB