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

设计模式---中介者模式

设计模式---中介者模式

  • 定义与设计思路
  • 中介者模式的引入:机场控制塔
  • 中介者模式的设计框架

定义与设计思路

  • 定义:用一个中介对象来封装一系列对象交互。中介者使各对象不需要相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式,属于行为型模式。

  • 设计思路:用一个中介对象来封装一系列的对象交互操作,中介者模式使得对象之间不需要显示的相互引用,从而使得系统或模块内部相互解耦,而且可以独立的改变它们至今的交互

中介者模式的引入:机场控制塔

想象一个繁忙的机场,有许多飞机在同一时间内起飞和降落。如果每架飞机都直接与其他飞机通信,协商谁该先起飞、谁该先降落,整个机场的调度将变得非常复杂。每架飞机都要知道其他所有飞机的状态、飞行路线、优先级等,导致信息的传递和处理变得混乱而低效。

问题:飞机之间的复杂通信
直接通信导致混乱: 每架飞机要知道并与其他所有飞机通信,管理起飞、降落的顺序会变得非常困难且危险。

  • 维护成本高: 增加或移除一架飞机,所有飞机的通信方式都需要更新,增加了维护的难度。
  • 耦合度过高: 每架飞机相互依赖,任何一个飞机的变动可能会影响整个系统的稳定性。

中介模式解决问题:引入机场控制塔
为了简化调度过程,机场引入了控制塔作为中介者。控制塔的职责是协调所有飞机的起飞和降落,保证每架飞机都能安全有- 序地运行。这样,每架飞机只需要与控制塔通信,而不需要关心其他飞机的具体状态。

  • 控制塔(中介者): 控制飞机的起飞和降落顺序,管理它们的路线和时间安排。
  • 飞机(同事类): 负责向控制塔报告自己的状态(如准备起飞、准备降落等),并接收控制塔的指令(如可以起飞或等待)。

中介模式的作用:
去耦合: 飞机之间不再直接通信,只需要和控制塔交互,这大大简化了飞机之间的相互依赖。
集中控制: 所有的调度逻辑都集中在控制塔中,便于统一管理,维护起来更加简单。
易于扩展: 新的飞机可以轻松加入机场系统,只需要和控制塔通信,而不需要重新调整其他飞机的通信逻辑。

中介者模式的设计框架

需要一个中介者类和同事类,目的是通过中介者类对象对象完成同事类实例之间的信息交互。其中,中介者类中需要有一个储存注册进来的同事对象的列表、发送消息的接口(协助同事实例完成消息的转发)、注册函数(完成同事实例的注册)。所有的同事类实例包含一个发布消息接口、接收消息的接口(接收中介转发的消息),另外包含一个中介实例成员变量(用于完成消息的转发的接口对象)。

中介模式的关键要素:

  • 中介者(Mediator): 中介者负责定义对象之间的通信接口,具体的通信逻辑则由具体的中介者实现。
  • 具体中介者(Concrete Mediator): 这是中介者的具体实现,它维护所有参与者对象,并处理这些对象之间的通信。
  • 同事类(Colleague): 这些是参与通信的对象,它们通过中介者进行相互通信,而不是直接引用其他同事对象。
#include <bits/stdc++.h>//
//中介者模式
//关键代码:对象 Colleague 之间的通信封装到一个类中单独处理
//class Mediator;//抽象人(同事类)
class Person
{
protected:std::shared_ptr<Mediator> m_mediator; //中介类实例
public:Person(const std::shared_ptr<Mediator> pMediator) : m_mediator(pMediator) {}//虚析构函数virtual ~Person() = default;//向中介发送信息virtual void SendMessage(const std::string &message) = 0;//从中介获取信息//message 中介向该对象发送的信息/从中介获取的信息virtual void GetMessage(const std::string &message) = 0;
};//抽象中介机构
class Mediator
{
public:virtual ~Mediator() = default;//由于后面this指针的原因,此处未采用智能指针virtual void Send(std::string message, const Person *from_person) const = 0;virtual void Register(std::shared_ptr<Person> pPerson) = 0;
};//租房者A
class RenterA : public Person
{
public:RenterA(const std::shared_ptr<Mediator> mediator) : Person(mediator) {}void SendMessage(const std::string &message) override{m_mediator->Send(message, this);}void GetMessage(const std::string &message) override{std::cout << "租房者A收到信息" << message << std::endl;;}
};//租房者B
class RenterB : public Person
{
public:RenterB(const std::shared_ptr<Mediator> mediator) : Person(mediator) {}void SendMessage(const std::string &message) override{m_mediator->Send(message, this);}void GetMessage(const std::string &message) override{std::cout << "租房者B收到信息" << message << std::endl;;}
};//房东
class Landlord : public Person
{
public:Landlord(const std::shared_ptr<Mediator> mediator) : Person(mediator) {}void SendMessage(const std::string &message) override{m_mediator->Send(message, this);}void GetMessage(const std::string &message) override{std::cout << "房东收到信息:" << message << std::endl;;}
};//房屋中介
class HouseMediator : public Mediator
{
private://也可以采用多个list,将多个房东放入一个list,将多个求租者放入一个liststd::vector<std::shared_ptr<Person>> m_pPersonList;
public:void Register(const std::shared_ptr<Person> pPerson) override{//没有添加该同事,则添加进去auto iter = m_pPersonList.begin();for (; iter != m_pPersonList.end(); ++iter){if (*iter == pPerson)break;}if (iter == m_pPersonList.end())m_pPersonList.emplace_back(pPerson);}void Send(std::string message, const Person *from_person) const override{//接收消息的对象为该对象的对应对象for (const auto item:m_pPersonList){//此处采用typeid,而非直接判断指针是否相等为同一个对象.if (typeid(*item.get()) != typeid(*from_person)){item->GetMessage(message);}}}
};int main() {std::shared_ptr<Mediator> pHouseMediator = std::make_shared<HouseMediator>();std::shared_ptr<Person> pRenterA = std::make_shared<RenterA>(pHouseMediator);std::shared_ptr<Person> pRenterB = std::make_shared<RenterB>(pHouseMediator);std::shared_ptr<Person> pLandlord = std::make_shared<Landlord>(pHouseMediator);pHouseMediator->Register(pRenterA);pHouseMediator->Register(pRenterB);pHouseMediator->Register(pLandlord);pLandlord->SendMessage("出租房子:中山路100号,50平米,2000元一个月");//所有的求租者将会收到该消息std::cout << std::string(50, '-') << std::endl;pRenterA->SendMessage("我想在中山路附近租套房子,价格1500元一个月");//所有的房东将会收到该消息return 0;
}

输出

租房者A收到信息出租房子:中山路100号,50平米,2000元一个月
租房者B收到信息出租房子:中山路100号,50平米,2000元一个月
--------------------------------------------------
租房者B收到信息我想在中山路附近租套房子,价格1500元一个月
房东收到信息:我想在中山路附近租套房子,价格1500元一个月

发送的消息通过中介转发给租房者,租房者发送的消息通过中介转发给

感谢大佬的讲解

https://blog.csdn.net/leonardohaig/article/details/109963550

相关文章:

设计模式---中介者模式

设计模式---中介者模式 定义与设计思路中介者模式的引入&#xff1a;机场控制塔中介者模式的设计框架 定义与设计思路 定义&#xff1a;用一个中介对象来封装一系列对象交互。中介者使各对象不需要相互引用&#xff0c;从而使其耦合松散&#xff0c;而且可以独立地改变它们之间…...

六氟化硫密度微水在线监测配套5孔M12格兰头航空插头插座

我们将为大家介绍如何使用六氟化硫密度微水在线监测配套5孔M12格兰头连接器。在本教程中&#xff0c;我们将向您展示简单易懂的步骤&#xff0c;让您轻松掌握。 所需材料&#xff1a; 1. 六氟化硫密度微水在线监测器 2. 5孔M12格兰头连接器 3. 电源线 4. 符合要求的电缆 5…...

linux -L4.linux 暂停和启动进程

接第3课&#xff0c;L3 第3课-查看进程 通过端口号&#xff0c;查看对应的进程 netstat -tulnp | grep :9513暂停这个进程 Kill -STOP 5376重启这个进程 Kill -CONT 5376要查看特定PID对应的端口&#xff0c;你可以使用netstat命令结合grep工具来过滤输出。以下是一个基于L…...

Java多线程编程-基础篇

多线程相关的概念 并发 并发是指在同一时间段内&#xff0c;两个或多个任务在同一个处理器上交替执行&#xff0c;使得在宏观上看起来像是同时进行。并发是通过快速切换任务来模拟同时执行的效果&#xff0c;实际上在任何一个时刻点上只有一个任务在执行。 也就是说&#xff0…...

【极限、数学】 NOIP 2018 提高组初赛试题 第 7 题详解(线段长度期望)

在一条长度为 1 1 1 的线段上随机取两个点&#xff0c;则以这两个点为端点的线段的期望长度是&#xff08; &#xff09;。 考虑将一个线段上平均分布有 n ( n ≥ 2 ) n(n\geq 2) n(n≥2) 个节点&#xff0c;其中首尾均有一个节点&#xff0c;那么我们就将一个线段均分为 n…...

《论网络安全体系设计》写作框架,软考高级系统架构设计师

论文真题 随着社会信息化的普及&#xff0c;计算机网络已经在各行各业得到了广泛的应用。目前&#xff0c;绝大多数业务处理几乎完全依赖计算机和网络执行&#xff0c;各种重要数据如政府文件、工资档案、财务账目和人事档案等均依赖计算机和网络进行存储与传输。另一方面&…...

这款开源的通用PDF处理神器,功能炸裂!

今天分享一款以PDF为中心的多功能办公学习工具箱软件&#xff0c;包含四大板块功能&#xff1a;PDF实用工具箱、Anki制卡神器、Anki最强辅助、视频笔记神器&#xff0c;软件功能众多且强大&#xff0c;熟练运用可以大幅提高办公和学习效率&#xff0c;绝对是您不可多得的效率神…...

RabbitMQ延迟消息——DelayExchange插件

什么是死信以及死信交换机 当一个队列中的消息满足下列情况之一时&#xff0c;可以成为死信&#xff1a; 1. 消费者使用basic.reject或 basic.nack声明消费失败&#xff0c;并且消息的requeue参数设置为false 2. 消息是一个过期消息&#xff0c;超时无人消费 3. 要投递的队列消…...

【系统规划与管理师】【案例分析】【考点】【答案篇】第5章 IT服务部署实施

【问题篇】☞【系统规划与管理师】【案例分析】【考点】【问题篇】第5章 IT服务部署实施 【移动端浏览】☞【系统规划与管理师】【案例分析】【模拟考题】章节考题汇总&#xff08;第5章&#xff09;&#xff08;答案篇&#xff09;&#xff08;共24个知识点&#xff09; 第5章…...

华为云服务器的数据库部署及管理

不管是终端数据上报到服务器进行存储&#xff0c;还是客户端的动态请求都需要用到数据库&#xff0c;因此这里对数据库的使用进行了一些记录&#xff0c;租用的是华为云的ECS弹性服务器&#xff08;Ubuntu18&#xff09;。下面以网页登录的账号信息Acount为例。 一、Mysql的安装…...

C#【必备技能篇】替换一个字节(byte)中连续几位(bit)的内容

文章目录 一、一个示例二、通用方法 一、一个示例 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace ConsoleApp1 {class Program{static void Main(string[] args){Method1();}public static…...

roboguide将tp程序转化为LS文本格式的方法

不同的软件版本可能操作不同&#xff0c;但是仍然可以参考文章中的办法。 我使用的版本如图所示&#xff1a; 1.首先&#xff0c;打开任意一个工程&#xff0c;如果没有&#xff0c;可以打开自带的示例。 如图&#xff0c;我打开了自带的示例&#xff0c;在帮助文档中可以找到…...

基于SpringBoot+Vue+MySQL的流浪猫狗宠物救助救援网站管理系统

系统展示 用户前台界面 管理员后台界面 系统背景 在当今社会&#xff0c;随着宠物数量的激增及人们关爱动物意识的提升&#xff0c;流浪猫狗问题日益严峻。为解决这一问题&#xff0c;构建一套高效、便捷的流浪猫狗宠物救助救援网站管理系统显得尤为重要。本系统基于SpringBoot…...

I/O 多路复用:`select`、`poll`、`epoll` 和 `kqueue` 的区别与示例

I/O 多路复用是指在一个线程内同时监控多个文件描述符&#xff08;File Descriptor, FD&#xff09;&#xff0c;以便高效地处理多个 I/O 事件。在 UNIX/Linux 和 BSD 系统中&#xff0c;select、poll、epoll、kqueue 都是实现 I/O 多路复用的系统调用。它们各有特点&#xff0…...

大数据之Flink(三)

9.3、转换算子 9.3.1、基本转换算子 9.3.1.1、映射map 一一映射 package transform;import bean.WaterSensor; import org.apache.flink.streaming.api.datastream.DataStreamSource; import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator; impor…...

【HCIA-Datacom】IPv4地址介绍

| | &#x1f449;个人主页&#xff1a;Reuuse 希望各位多多支持&#xff01;❀ | &#x1f449;HCIA专栏博客 | 最后如果对你们有帮助的话希望有一个大大的赞&#xff01; | ⭐你们的支持是我最大的动力&#xff01;⭐ | 目录 IPv4地址定义IPv4地址分类方式二级目录三级目录 I…...

maven父子工程多模块如何管理统一的版本号?

1.为什么要统一管理&#xff1f; maven父子工程多模块&#xff0c;每个模块还都可以独立存在&#xff0c;子模块往往通常希望和父工程保持一样的版本&#xff0c;如果每个工程单独定义版本号&#xff0c;后期变更打包也非常麻烦&#xff0c;如何维护一个全局的版本号呢&#x…...

JavaScript --函数的作用域(全局和局部)

全局作用域 全局作用域&#xff0c;就算不在一个script标签也能调用 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta nam…...

贪吃蛇项目实现(C语言)——附源码

前言 贪吃蛇是一款十分经典的游戏&#xff0c;其通过控制贪吃蛇的上下左右移动来吃食物&#xff0c;延长自己的身体&#xff0c;也会因为撞到墙体和自身而死亡。下面我们通过C语言来实现贪吃蛇。 1.技术要点 C语言枚举&#xff0c;结构体&#xff0c;链表&#xff0c;动态内…...

【C++】42道面试经典问题总结

C this指针是干什么用的&#xff1f; 假如一个类型定义了很多对象&#xff0c;类里面有很多定义的私有成员变量&#xff0c;共享一套成员方法。通过this指针这可以区分方法、变量是操作的哪个对象的。 C的new和delete&#xff0c;new[]和delete[]可以混用吗&#xff1f; 一般来…...

Godot卡牌游戏框架终极指南:3小时从零构建专业级卡牌游戏

Godot卡牌游戏框架终极指南&#xff1a;3小时从零构建专业级卡牌游戏 【免费下载链接】godot-card-game-framework A framework which comes with prepared scenes and classes to kickstart your card game, as well as a powerful scripting engine to use to provide full r…...

qmcdump:专业解决QQ音乐加密音频格式兼容性问题

qmcdump&#xff1a;专业解决QQ音乐加密音频格式兼容性问题 【免费下载链接】qmcdump 一个简单的QQ音乐解码&#xff08;qmcflac/qmc0/qmc3 转 flac/mp3&#xff09;&#xff0c;仅为个人学习参考用。 项目地址: https://gitcode.com/gh_mirrors/qm/qmcdump 在数字音乐时…...

XHS-Downloader:小红书内容采集与管理的全栈解决方案

XHS-Downloader&#xff1a;小红书内容采集与管理的全栈解决方案 【免费下载链接】XHS-Downloader 小红书&#xff08;XiaoHongShu、RedNote&#xff09;链接提取/作品采集工具&#xff1a;提取账号发布、收藏、点赞、专辑作品链接&#xff1b;提取搜索结果作品、用户链接&…...

终极指南:3步实现PotPlayer实时字幕翻译,外语视频无障碍观看

终极指南&#xff1a;3步实现PotPlayer实时字幕翻译&#xff0c;外语视频无障碍观看 【免费下载链接】PotPlayer_Subtitle_Translate_Baidu PotPlayer 字幕在线翻译插件 - 百度平台 项目地址: https://gitcode.com/gh_mirrors/po/PotPlayer_Subtitle_Translate_Baidu 还…...

Iris API错误处理机制与嵌入式系统优化实践

1. Iris API错误处理机制解析在嵌入式系统开发中&#xff0c;API的健壮性直接影响整个系统的稳定性。Iris框架作为ARM架构下的核心组件&#xff0c;其错误处理机制基于JSON-RPC 2.0规范进行了深度定制&#xff0c;特别适合资源受限的嵌入式环境。与通用Web API不同&#xff0c;…...

免费开源鼠标连点器终极指南:5分钟掌握高效自动化技巧

免费开源鼠标连点器终极指南&#xff1a;5分钟掌握高效自动化技巧 【免费下载链接】MouseClick &#x1f5b1;️ MouseClick &#x1f5b1;️ 是一款功能强大的鼠标连点器和管理工具&#xff0c;采用 QT Widget 开发 &#xff0c;具备跨平台兼容性 。软件界面美观 &#xff0c;…...

ARM Debug Interface v5.1架构解析与调试实践

1. ARM Debug Interface v5.1架构深度解析1.1 调试接口技术演进与核心价值ARM调试接口(ADI)技术历经多次迭代&#xff0c;v5.1版本作为当前主流标准&#xff0c;在嵌入式系统调试领域确立了关键地位。调试接口本质上是处理器核与外部调试工具之间的标准化通信桥梁&#xff0c;其…...

多智能体涌现环境:从局部交互到群体智能的深度解析与实践

1. 项目概述&#xff1a;多智能体涌现环境的深度探索最近在复现和深入研究一个名为“multi-agent-emergence-environments”的开源项目&#xff0c;它来自OpenAI。这个项目名听起来有点学术&#xff0c;但它的核心思想非常迷人&#xff1a;在一个模拟的物理沙盒环境中&#xff…...

Flutter桌面端窗口控制:从隐藏标题栏到自定义全屏交互

1. 为什么需要自定义窗口控制&#xff1f; 当你用Flutter开发Windows桌面应用时&#xff0c;系统默认的标题栏和窗口样式往往显得格格不入。想象一下&#xff0c;你精心设计了一套深色主题的UI&#xff0c;结果顶部突然冒出一条灰白色的标准标题栏——就像给西装革履的绅士戴了…...

如何让Photoshop图层批量导出速度提升3倍?这个开源脚本做到了!

如何让Photoshop图层批量导出速度提升3倍&#xff1f;这个开源脚本做到了&#xff01; 【免费下载链接】Photoshop-Export-Layers-to-Files-Fast This script allows you to export your layers as individual files at a speed much faster than the built-in script from Ado…...