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

news/2025/1/17 13:14:25/

中介者模式 (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.ppmy.cn/news/1563888.html

相关文章

如何学习Transformer架构

Transformer架构自提出以来&#xff0c;在自然语言处理领域引发了革命性的变化。作为一种基于注意力机制的模型&#xff0c;Transformer解决了传统序列模型在并行化和长距离依赖方面的局限性。本文将探讨Transformer论文《Attention is All You Need》与Hugging Face Transform…

细说STM32F407单片机窗口看门狗WWDG的原理及使用方法

目录 一、窗口看门狗的工作原理 1、递减计数器 2、窗口值和比较器 3、看门狗的启动 4、提前唤醒中断 二、窗口看门狗的HAL驱动程序 1、窗口看门狗初始化 2.窗口看门狗刷新 3.EWI中断及其处理 三、不开启EWI的WWDG示例 1、示例功能 2、项目设置 &#xff08;1&…

Vue 和 uniApp 中 CSS 样式差别

之前一直在做vue2的项目&#xff0c;最近开始uniapp的项目&#xff0c;发现两种项目之间css还是有亿点区别的。 一、布局单位 Vue 2 项目&#xff1a; 通常使用 px 作为主要的长度单位&#xff0c;这是一个绝对单位&#xff0c;在不同设备屏幕上显示的物理尺寸相同。例如&am…

备忘录清单工具:四款电脑桌面备忘录工具分享

在快节奏的现代生活中&#xff0c;无论是工作还是学习&#xff0c;我们每天都会面临各种各样的任务和待办事项。为了更好地管理这些繁杂的事务&#xff0c;一款好用的电脑桌面备忘录工具无疑是提升效率的关键。今天&#xff0c;就让我们一起来看看四款备受好评的备忘录工具。 …

30分钟内搭建一个全能轻量级springboot 3.4 + 脚手架 <5> 5分钟集成好caffeine并使用注解操作缓存

快速导航 <1> 5分钟快速创建一个springboot web项目 <2> 5分钟集成好最新版本的开源swagger ui&#xff0c;并使用ui操作调用接口 <3> 5分钟集成好druid并使用druid自带监控工具监控sql请求 <4> 5分钟集成好mybatisplus并使用mybatisplus generator自…

C语言预处理艺术:编译前的魔法之旅

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文一、预处理的作用与流程&#xf…

出差人员携带的电脑文件信息安全如何保障?

在数字化时代&#xff0c;企业数据已成为核心资产&#xff0c;而出差人员作为企业与外界交流的桥梁&#xff0c;其携带的数据安全更是重中之重。为了确保出差期间企业数据的安全&#xff0c;除了加强员工的安全意识培训外&#xff0c;还需采取一系列技术措施。 一方面&#xff…

算法【Java】—— 动态规划之子数组问题

最大子数组 https://leetcode.cn/problems/maximum-subarray 状态表示&#xff1a;dp 表每一个位置表示当前位置的最大子数组的和 状态转移方程推导&#xff1a;首先明确子数组是连续&#xff0c;那么当前位置的子数组最大的和要么是自己&#xff0c;要么是前一个位置的最大子…