C++ 设计模式之中介者模式

C++ 设计模式之中介者模式

简介

1、中介者模式(Mediator)是一种行为型设计模式,它用于减少对象之间的直接耦合,使得这些对象可以松散地耦合在一起,并且可以通过一个中介者对象来间接地交互。中介者模式通常用于一组对象以定义良好但是复杂的方式进行通信的场合。

2、中介者模式 (Mediator)应用场景包括但不限于:
1、当一组对象以定义明确但复杂的方式交互时,特别是当你不想让这些交互形成一个“不明确的对象网”时。
2、当你想重用一个对象在不同的场景中,而这些场景需要大量不同的交互时。

3、中介者模式 (Mediator)的构成
3.1、中介者(Mediator):定义了一个接口,用于与各个同事对象通信,并封装了协调各个同事对象之间的交互行为。

class ChatRoom
{
public:virtual void sendMessage(const std::string& sender, const std::string& receiver, const std::string& message) = 0;
};

3.2、同事类:每一个同事类都知道中介者对象,并且与其他的同事对象通信时,一定要通过中介者对象协作。同事类之间一般不直接引用。

class User
{
public:User(ChatRoom* chat, std::string n);std::string GetName();ChatRoom* GetChatRoom();virtual void send(const std::string& message) = 0;virtual void receive(const std::string& sender, const std::string& message) = 0;private:ChatRoom* mediator;std::string name;
};

4、中介者模式 (Mediator)的优点
4.1、降低系统复杂性: 中介者模式简化了对象之间的交互,使对象不需要显式地相互引用。
4.2、提升对象的复用性: 减少对象间依赖,有利于提高对象的可复用性。
4.3、集中控制交互: 将系统的交互复杂性集中到中介者中,使变更和维护变得更容易。
4.4、增强系统的可维护性:如果对象间的交互非常复杂,把这些交互逻辑放在中介者中可以集中管理,提高系统的可维护性。

5、中介者模式 (Mediator)的缺点
5.1、中介者可能过于复杂: 中介者自身可能变得复杂且难以维护,因为所有的交互逻辑都集中于一处。
5.2、过度集中化: 中介者控制了所有的交互,如果设计不当,可能导致中介者变成一个上帝对象,违反了单一职责原则。

简单示例

1、定义

// 中介者
class ChatRoom
{
public:virtual void sendMessage(const std::string& sender, const std::string& receiver, const std::string& message) = 0;
};// 同事类
class User
{
public:User(ChatRoom* chat, std::string n);std::string GetName();ChatRoom* GetChatRoom();virtual void send(const std::string& message) = 0;virtual void receive(const std::string& sender, const std::string& message) = 0;private:ChatRoom* mediator;std::string name;
};// 具体中介者
class ConcreteChatRoom : public ChatRoom
{
public:void addUser(User* user);void sendMessage(const std::string& sender, const std::string& receiver, const std::string& message);private:std::map<std::string, User*> users;
};// 具体同事类
class ConcreteUser : public User
{
public:ConcreteUser(ChatRoom* chat, std::string n);void send(const std::string& message);void receive(const std::string& sender, const std::string& message);
};

2、实现

User::User(ChatRoom* chat, std::string n) : mediator(chat), name(n)
{}std::string User::GetName()
{return name;
}ChatRoom* User::GetChatRoom()
{return mediator;
}void ConcreteChatRoom::addUser(User* user)
{users[user->GetName()] = user;
}void ConcreteChatRoom::sendMessage(const std::string& sender, const std::string& receiver, const std::string& message)
{if (receiver == "All"){for (auto user : users){if (sender != user.first){user.second->receive(sender, message);}}}else{if (users.find(sender) != users.end()){users[sender]->receive(sender, message);}}
}ConcreteUser::ConcreteUser(ChatRoom* chat, std::string n) : User(chat, n)
{}void ConcreteUser::send(const std::string& message)
{GetChatRoom()->sendMessage(GetName(), "All", message);
}void ConcreteUser::receive(const std::string& sender, const std::string& message)
{std::cout << GetName() << " received from " << sender << ": " << message << std::endl;
}

3、调用

ConcreteChatRoom chatRoom;
User* alice = new ConcreteUser(&chatRoom, "Alice");
User* bob = new ConcreteUser(&chatRoom, "Bob");chatRoom.addUser(alice);
chatRoom.addUser(bob);alice->send("Hello Bob!");
bob->send("Hello Alice!");delete alice;
delete bob;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/38079.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux基础篇——目录结构

基本介绍 Linux的文件系统是采用级层式的树状目录结构&#xff0c;在此结构中的最上层是根目录"/"&#xff0c;然后在根目录下再创建其他的目录 在Linux中&#xff0c;有一句经典的话&#xff1a;在Linux世界里&#xff0c;一切皆文件 Linux中根目录下的目录 具体的…

木各力“GERRI”被“GREE”格力无效宣告成功

近日“GERRI”被“GREE”格力无效宣告成功&#xff0c;“GERRI”和“GREE”近似不&#xff0c;如果很近似当初就不会通过初审和下商标注册证&#xff0c;但是如果涉及知名商标和驰名商标&#xff0c;人家就可以异议和无效。 “GERRI”在被无效宣告时&#xff0c;引用了6个相关的…

(笔记)M1使用hombrew安装qemu

homebrew formulae的网址&#xff1a; qemu — Homebrew Formulae​​​​​​ brew install qemu 如果要支持OpenGL&#xff0c;执行下面的命令 brew tap knazarov/qemu-virglbrew install qemu-virgl 报错Error: qemu-virgl: Failed to download resource "qemu-virgl…

232. 用栈实现队列 (Implement Queue using Stacks)

用栈实现队列 (Implement Queue using Stacks) 题目描述 使用两个栈实现一个队列。队列的操作包括 push(x)、pop()、peek() 和 empty()。 示例&#xff1a; MyQueue queue new MyQueue();queue.push(1); queue.push(2); queue.peek(); // 返回 1 queue.pop(); // 返回…

深入剖析C++多态的实现与原理-详解 (三万字)

100编程书屋_孔夫子旧书网 目录 一、多态基础 虚函数 虚函数的继承虚类/虚基类重写/覆盖 条件:概念:多态的条件 其他的多态行为 多态中子类可以不写virtual协变 代码举例继承遗留问题解决 析构函数 具体解决方式:题目1 答案:解析:题目2 答案:C11 override和final final 功能1…

web渗透-反序列化漏洞

一、简介 就是把一个对象变成可以传输的字符串&#xff0c;目的就是为了方便传输。假设&#xff0c;我们写了一个class,这个class里面存有一些变量。当这个class被实例化了之后&#xff0c;在使用过程中里面的一些变量值发生了改变。以后在某些时候还会用到这个变量&#xff0…

ctfshow sqli-libs web541--web551

web541 and和or 被替换为空格 # 还有 1 也是不能生效的?id-1 union select 1,2,3-- 双写绕过 ?id-1 union select 1,(select group_concat(table_name) from infoorrmation_schema.tables where table_schemactfshow),3 -- flags?id-1 union select 1,(select group_con…

Nginx软件的安装及使用

Nginx概述 Nginx功能介绍 静态的web资源服务器html&#xff0c;图片&#xff0c;js&#xff0c;css&#xff0c;txt等静态资源http/https协议的反向代理 &#xff0c;7层 url结合FastCGI /uWSGI/SCGI等协议反向代理动态资源请求tcp/udp协议的请求转发&#xff08;反向代理…

计算二叉树的深度

#include <iostream> // 定义二叉树节点 struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; // 递归函数来计算二叉树的深度 int maxDepth(TreeNode* root) { i…

【Linux】Linux系统配置,linux的交互方式

1.Linux系统环境安装 有三种方式 裸机安装或者双系统 -- 不推荐虚拟机安装 --- 不推荐云服务器/安装简单&#xff0c; 维护成本低——推荐&#xff0c; 未来学习效果好 我们借助云服务器 云服务器&#xff08;Elastic Compute Service&#xff0c;ECS&#xff09;的标准定义…

以太网交换机原理

没有配置&#xff0c;比较枯燥&#xff0c;二可以认识线缆&#xff0c; 三比较重要&#xff0c;慢慢理解&#xff0c;事半功倍。 各位老少爷们&#xff0c;在下给大家说段以太网交换机原理&#xff0c;说得不好大家多多包涵&#xff0c;说得好呢&#xff0c;大家叫个好&#x…

【面试系列】数据分析师高频面试题及详细解答

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来&#xff1a;详细讲解AIGC的概念、核心技术、…

数据库回表介绍

索引覆盖 索引覆盖或称为覆盖索引&#xff0c;是数据库中的一种优化手段当我们在执行一个sql查询时&#xff0c;如果只需要查询某几个字段的值&#xff0c;并且这几个字段的数据都已经被包含在某一个索引中(而不是全表扫描)&#xff0c;那么数据库引擎就会直接通过这个索引来取…

使用slenium对不同元素进行定位实战篇~

单选框Radio定位&#xff1a; 单选框只能点击一个&#xff0c;并且点击之后并不会被取消&#xff0c;而多选框&#xff0c;能够点击多个&#xff0c;并且点击之后可以取消 import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; imp…

FastAPI教程III

本文参考FastAPI教程https://fastapi.tiangolo.com/zh/tutorial 这部分暂无需求的没有记录&#xff0c;仅放置标题。 依赖项 安全性 中间件 你可以向FastAPI应用添加中间件。 ”中间件“是一个函数&#xff0c;它在每个请求被特定的路径操作处理之前&#xff0c;以及在每个…

PyCharm 2024.1 版本更新亮点:智能编程,高效协作

目录 1. 前言2. 更新内容2.1 智能编码体验2.1.1 Hugging Face 文档预览2.1.2 全行代码补全 2.2 提升编辑器体验2.2.1 粘性行功能2.2.2 编辑器内代码审查 2.3 全新终端体验&#xff08;测试版&#xff09;2.3.1 新终端 Beta 2.4 智能助手&#xff08;特定版本和专业用户&#xf…

短视频矩阵系统:打造品牌影响力的新方式

一、短视频矩阵概念 短视频营销革命&#xff1a;一站式解决策略&#xff01;短视频矩阵系统是一款专为企业营销设计的高效工具&#xff0c;旨在通过整合和优化众多短视频平台资源&#xff0c;为企业呈现一个全面的短视频营销策略。该系统致力于协助企业以迅速且高效的方式制作…

小白学webgl合集-WebGL中给图片添加背景

一.实现效果 二.逻辑 为了在WebGL中给图片添加背景&#xff0c;主要的逻辑步骤包括初始化WebGL上下文、编写和编译着色器、创建和绑定缓冲区、加载和配置纹理以及绘制场景。以下是代码逻辑的详细说明&#xff1a; 1. 获取WebGL上下文 首先&#xff0c;通过获取<canvas>…

WEB与低代码:B/S架构在开发中的应用与优势

在互联网迅猛发展的今天&#xff0c;WEB应用已经成为人们日常生活和工作中不可或缺的一部分。随着技术的进步和需求的多样化&#xff0c;开发高效、灵活且易于维护的WEB应用变得尤为重要。B/S架构&#xff08;Browser/Server Architecture&#xff09;作为一种常见的WEB应用架构…

天天生鲜数据库设计

目录 1、用户表2、商品表SKU和SPU的概念区分3、商品表改进4、redis实现购物车模块&#xff0c;redis保存用户最近浏览记录5、订单表 设计表时&#xff0c;出现一对多的情况&#xff0c;可以将对应的“多”单独拿出来重新设计一个表 1、用户表 &#xff08;灰色的部分不存在表…