当前位置: 首页 > 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; 一般来…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...