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

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

  1. 中介者模式介绍

    • 定义:中介者模式是一种行为设计模式,它通过引入一个中介者对象来封装一系列对象之间的交互。中介者使得各个对象之间不需要显式地相互引用,从而降低了它们之间的耦合度,并且可以更方便地对它们的交互进行管理和协调。
    • 工作原理:系统中的多个对象(同事对象)之间存在复杂的相互引用和交互关系,这些关系使得系统变得复杂且难以维护。中介者模式将这些交互逻辑集中到一个中介者对象中,同事对象只需要和中介者对象进行通信,而不用直接与其他同事对象交互。当一个同事对象的状态发生变化或者需要执行某些操作时,它通过中介者对象来通知其他相关的同事对象。
    • 类比:可以将中介者模式类比为机场的塔台(中介者)和飞机(同事对象)之间的关系。飞机之间不需要直接通信来协调起降等操作,而是通过塔台来传递信息和指令。塔台知道每架飞机的状态和需求,并且根据这些信息来协调飞机的行动,确保飞行安全和秩序。
  2. 角色构成及职责

    • 中介者(Mediator)接口或抽象类:定义了同事对象与中介者进行通信的接口方法。通常包括用于通知中介者对象状态变化的方法,以及中介者用来通知同事对象执行操作的方法。
    • 具体中介者(Concrete Mediator)类:实现了中介者接口,它包含了对各个同事对象的引用,并且实现了协调同事对象之间交互的具体逻辑。例如,在一个聊天软件的中介者实现中,具体中介者需要知道每个聊天用户(同事对象)的信息,并且根据用户发送的消息来转发给其他相关用户。
    • 同事(Colleague)接口或抽象类:定义了同事对象的基本接口,包括与中介者通信的方法。同事对象通过这些方法来向中介者发送自己的状态变化信息或者接收中介者传来的通知。
    • 具体同事(Concrete Colleague)类:实现了同事接口,每个具体同事对象代表系统中的一个实体,它们有自己的状态和行为。当自己的状态发生变化时,通过中介者接口方法通知中介者;同时,也会接收中介者传来的通知并执行相应的操作。
      在这里插入图片描述
  3. 优点

    • 降低耦合度:同事对象之间的直接依赖关系被转移到中介者对象上,使得同事对象之间的耦合度大大降低。这样,当一个同事对象发生变化时,对其他同事对象的影响主要通过中介者来控制,减少了系统中复杂的连锁反应。
    • 易于维护和扩展:由于交互逻辑集中在中介者对象中,所以当需要修改或扩展系统的交互方式时,只需要修改中介者对象的代码,而不需要在多个同事对象中进行分散的修改。同时,添加新的同事对象也相对简单,只需要在中介者对象中添加对新同事对象的引用和相应的交互逻辑即可。
    • 提高代码的复用性:中介者对象的交互逻辑可以在不同的系统中复用。例如,一个通用的消息转发中介者可以应用于多种不同的消息传递场景,只要同事对象遵循相同的接口与中介者进行通信。
  4. 缺点

    • 中介者可能变得复杂:如果系统中的同事对象较多,交互逻辑复杂,那么中介者对象可能会变得非常庞大和复杂,包含大量的协调代码,导致中介者本身的维护难度增加。
    • 系统的分布式处理能力受限:中介者模式将交互集中在一个中介者对象上,对于一些需要分布式处理或者高度并行处理的系统,可能不太适合,因为所有的交互都需要经过中介者,可能会成为性能瓶颈。
  5. 应用场景

    • 图形用户界面(GUI)开发:在GUI系统中,多个控件(如按钮、文本框、下拉菜单等)之间可能存在复杂的交互关系。例如,当用户在一个文本框中输入内容后,可能需要更新其他相关控件的显示状态。通过中介者模式,可以将这些控件之间的交互逻辑封装在一个中介者对象中,使得控件之间的耦合度降低,便于维护和扩展。
    • 游戏开发:在游戏中,不同的游戏角色、道具、场景元素之间可能需要进行各种交互。例如,当一个角色捡起一个道具时,可能会触发其他角色的反应或者场景的变化。使用中介者模式可以有效地管理这些交互,使游戏的逻辑更加清晰。
    • 分布式系统中的消息传递:在分布式系统中,多个节点之间需要传递消息和协调工作。虽然中介者模式在分布式处理方面有一定的局限性,但在一些相对简单的分布式消息传递场景中,通过一个中介者节点来转发和协调消息,可以降低节点之间的直接通信复杂度。
  6. C++代码示例

    • 中介者接口
      • class Mediator {
        public:virtual void notify(const std::string& sender, const std::string& event) = 0;
        };
        
    • 同事接口
      • class Colleague {
        protected:Mediator* mediator;
        public:Colleague(Mediator* m) : mediator(m) {}virtual void send(const std::string& event) = 0;virtual void receive(const std::string& sender, const std::string& event) = 0;
        };
        
    • 具体同事类A
      • class ConcreteColleagueA : public Colleague {
        public:ConcreteColleagueA(Mediator* m) : Colleague(m) {}void send(const std::string& event) override {mediator->notify("ConcreteColleagueA", event);}void receive(const std::string& sender, const std::string& event) override {if (sender == "ConcreteColleagueB") {std::cout << "ConcreteColleagueA received event '" << event << "' from ConcreteColleagueB" << std::endl;}}
        };
        
    • 具体同事类B
      • class ConcreteColleagueB : public Colleague {
        public:ConcreteColleagueB(Mediator* m) : Colleague(m) {}void send(const std::string& event) override {mediator->notify("ConcreteColleagueB", event);}void receive(const std::string& sender, const std::string& event) override {if (sender == "ConcreteColleagueA") {std::cout << "ConcreteColleagueB received event '" << event << "' from ConcreteColleagueA" << std::endl;}}
        };
        
    • 具体中介者类
      • class ConcreteMediator : public Mediator {
        private:ConcreteColleagueA* colleagueA;ConcreteColleagueB* colleagueB;
        public:void setColleagueA(ConcreteColleagueA* a) { colleagueA = a; }void setColleagueB(ConcreteColleagueB* b) { colleagueB = b; }void notify(const std::string& sender, const std::string& event) override {if (sender == "ConcreteColleagueA") {colleagueB->receive(sender, event);} else if (sender == "ConcreteColleagueB") {colleagueA->receive(sender, event);}}
        };
        
    • 使用示例
      • int main() {ConcreteMediator mediator;ConcreteColleagueA colleagueA(&mediator);ConcreteColleagueB colleagueB(&mediator);mediator.setColleagueA(&colleagueA);mediator.setColleagueB(&colleagueB);colleagueA.send("Hello from A");colleagueB.send("Hi from B");return 0;
        }
        
    • 在这个代码示例中,Mediator 是中介者接口,定义了 notify 方法用于接收同事对象的通知。Colleague 是同事接口,包含了发送消息和接收消息的方法。ConcreteColleagueAConcreteColleagueB 是具体同事类,它们通过中介者来发送和接收消息。ConcreteMediator 是具体中介者类,它包含了对两个具体同事对象的引用,并在 notify 方法中实现了根据发送者来通知相应同事对象接收消息的逻辑。在 main 函数中,创建了中介者、同事对象,并将同事对象与中介者关联起来,然后通过同事对象发送消息来演示中介者模式的消息传递过程。

C++代码示例2

#include<iostream>
#include<string>
using namespace std;
class Country;
//抽象类  联合国
class UN
{
public:virtual void delcare(string message , Country *m_country){}virtual void initcountry(Country*s1,Country*s2){};
};
//国家
class Country
{
protected:UN *m_un;
public:Country(UN* name):m_un(name){}virtual void delcare(string m_message){}};
//美国
class USA:public Country
{
public:USA(UN* name):Country(name){}void delcare(string message){cout<<"美国: "<<message<<endl;}
};
//伊拉克
class Iraq:public Country
{
public:Iraq(UN* name):Country(name){}void delcare(string message){cout<<"伊拉克:"<<message<<endl;}
};//安理会
class Security:public UN
{
private:Country *m_usa;Country *m_iraq;public:void initcountry(Country*s1 , Country*s2){m_usa = s1;m_iraq = s2;}void delcare(string message , Country *m_country){if(m_country==m_usa){m_usa->delcare(message);}else{m_iraq->delcare(message);}}
};int main()
{UN *m_sec = new Security();//创建安理会Country*country_usa = new USA(m_sec);//创建美国Country*country_iraq = new Iraq(m_sec);//创建伊拉克,美国和伊拉克有共同的中介者:安理会,m_secm_sec->initcountry(country_usa,country_iraq);m_sec->delcare("我要干死你" , country_usa);m_sec->delcare("来呀,cnm,互相伤害呀" , country_iraq);cout<<endl<<endl;return 0;
}

相关文章:

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

中介者模式介绍 定义&#xff1a;中介者模式是一种行为设计模式&#xff0c;它通过引入一个中介者对象来封装一系列对象之间的交互。中介者使得各个对象之间不需要显式地相互引用&#xff0c;从而降低了它们之间的耦合度&#xff0c;并且可以更方便地对它们的交互进行管理和协调…...

重温设计模式--设计模式七大原则

文章目录 1、开闭原则&#xff08;Open - Closed Principle&#xff0c;OCP&#xff09;定义&#xff1a;示例&#xff1a;好处&#xff1a; 2、里氏替换原则&#xff08;Liskov Substitution Principle&#xff0c;LSP&#xff09;定义&#xff1a;示例&#xff1a;好处&#…...

LeetCode429周赛T4

最小化二进制字符串中最长相同子字符串的长度 在处理二进制字符串问题时&#xff0c;优化字符串结构以满足特定条件是一项常见的挑战。本文将探讨一个具体的问题&#xff1a;给定一个长度为 n 的二进制字符串 s 和一个整数 numOps&#xff0c;通过最多 numOps 次位翻转操作&am…...

详解MySQL在Windows上的安装

目录 查看电脑上是否安装了MySQL 下载安装MySQL 打开MySQL官网&#xff0c;找到DOWNLOADS 然后往下翻&#xff0c;找到MySQL Community(GPL) Downloads>> 然后找到MySQL Community Server 然后下载&#xff0c;选择No thanks,just start my download. 然后双击进行…...

【Python使用】嘿马python高级进阶全体系教程第10篇:静态Web服务器-返回固定页面数据,1. 开发自己的静态Web服务器【附代码文档】

本教程的知识点为&#xff1a;操作系统 1. 常见的操作系统 4. 小结 ls命令选项 2. 小结 mkdir和rm命令选项 1. mkdir命令选项 压缩和解压缩命令 1. 压缩格式的介绍 2. tar命令及选项的使用 3. zip和unzip命令及选项的使用 4. 小结 编辑器 vim 1. vim 的介绍 2. vim 的工作模式 …...

软件测试面试题和简历模板(面试前准备篇)

一、问题预测 1、让简单介绍下自己&#xff08;这个不用说了每次面试开场&#xff09; 面试官&#xff0c;你好&#xff0c;我叫xxx&#xff0c;xx年本科毕业&#xff0c;从事软件测试将近3年的时间。在此期间做过一些项目也积累过一些经验&#xff0c;能够独立地完成软件测试…...

Linux 基本使用和程序部署

1. Linux 环境搭建 1.1 环境搭建方式 主要有 4 种&#xff1a; 直接安装在物理机上。但是Linux桌面使用起来非常不友好&#xff0c;所以不建议。[不推荐]。使用虚拟机软件&#xff0c;将Linux搭建在虚拟机上。但是由于当前的虚拟机软件(如VMWare之类的)存在一些bug&#xff…...

uniapp微信小程序,使用fastadmin完成一个一键获取微信手机号的功能

前端部分 点击按钮&#xff0c;获取手机号 <button open-type"getPhoneNumber" getphonenumber"bindGetPhoneNumber" hover-class"none"class"btn-purity">一键获取</button> 传入openid和code bindGetPhoneNumber(e) …...

CSS系列(27)- 图形与滤镜详解

前端技术探索系列&#xff1a;CSS 图形与滤镜详解 &#x1f3a8; 致读者&#xff1a;探索CSS的艺术表现力 &#x1f44b; 前端开发者们&#xff0c; 今天我们将深入探讨 CSS 图形和滤镜效果&#xff0c;学习如何创建引人注目的视觉效果。 基础图形 &#x1f680; 几何形状…...

Docker 技术系列之安装多版本Mysql5.6和Mysql5.7

image 大家好&#xff0c;后面的就不是关于MAC专有的内容&#xff0c;基本是跟Java环境&#xff0c;基础技术方面有关。所以这个教程对于在linux系统还是macOS都是通用的&#xff0c;不用担心。 上一篇&#xff0c;我们安装好对应的Docker之后&#xff0c;感受到了它的便利。接…...

理解并使用Linux 内核中的 Tracepoint

理解并使用Linux 内核中的 Tracepoint 1. 引言 1.1 为什么需要 Tracepoint&#xff1f; 在内核调试与性能分析中&#xff0c;传统的 printk 方法虽然简单直接&#xff0c;但存在几个显著的局限性&#xff1a; 日志噪音&#xff1a;printk 会将所有输出无差别地记录到系统日…...

centos7中Gbase8s数据库安装,以及数据导入遇到的一系列问题

centos7中Gbase8s数据库安装&#xff0c;以及遇到的一系列问题 以下是我在centos7上安装gbase8s数据库遇到的一系列问题&#xff0c;包括数据库安装&#xff0c;数据导入&#xff0c;数据连接&#xff0c;不能完全作为标准&#xff0c;只可作为类似问题参考&#xff0c;有问题…...

AW36518芯片手册解读(3)

接前一篇文章&#xff1a;AW36518芯片手册解读&#xff08;2&#xff09; 二、详述 3. 功能描述 &#xff08;1&#xff09;上电复位 当电源电压VIN降至预定义电压VPOR&#xff08;典型值为2.0V&#xff09;以下时&#xff0c;该设备会产生复位信号以执行上电复位操作&#x…...

MySQL的REPEATABLE READ事务隔离级别

本文隔离级别&#xff1a; T1内读T2的update数据 首先开两个事务&#xff08;左二&#xff09; 事务1修改成李四,提交 事务2再读还是张三&#xff0c;也就是说&#xff0c;记录的数据从事务开始时一直到结束&#xff0c;读的都是同一个版本,读不到T2未提交的此条记录修改&…...

sqoop的参数有哪些?

Sqoop 是一款用于在 Hadoop 与关系型数据库之间进行数据传输的工具&#xff0c;它有很多参数&#xff0c;可分为通用参数、导入参数和导出参数等&#xff0c;以下是一些常见的参数介绍&#xff1a; 通用参数 --connect 说明&#xff1a;指定要连接的关系型数据库的 JDBC URL。…...

动态规划<四> 回文串问题(含对应LeetcodeOJ题)

目录 引例 其余经典OJ题 1.第一题 2.第二题 3.第三题 4.第四题 5.第五题 引例 OJ 传送门Leetcode<647>回文子串 画图分析&#xff1a; 使用动态规划解决 原理&#xff1a;能够将所有子串是否是回文的信息保存在dp表中 在使用暴力方法枚举出所有子串&#xff0c;是…...

跨模态知识迁移:基于预训练语言模型的时序数据建模

在NLP和CV领域&#xff0c;通常通过在统一的预训练模型上进行微调&#xff0c;能够在各自领域的下游任务中实现SOTA&#xff08;最先进&#xff09;的结果。然而&#xff0c;在时序预测领域&#xff0c;由于数据量相对较少&#xff0c;难以训练出一个统一的预训练模型来覆盖所有…...

重温设计模式--职责链模式

文章目录 职责链模式的详细介绍C 代码示例C示例代码2 职责链模式的详细介绍 定义与概念 职责链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为型设计模式&#xff0c;它旨在将请求的发送者和多个接收者解耦&#xff0c;让多个对象都有机会处理请求&a…...

git冲突解决

git冲突解决 最近遇到了一次git冲突的问题 起因是因为最近公司数据推送部分重构&#xff0c;负责重构的同事就改动了我的一小部分推送的代码&#xff0c;然后等我开发完合并到远程master的时候&#xff0c;报了merge冲突。我对于git工具确实不是很熟练&#xff0c;只是学习了…...

Java学习笔记(14)--面向对象编程

面向对象基础 学习资料来自多态 - Java教程 - 廖雪峰的官方网站 目录 面向对象基础 Override 多态 举个例子 覆写Object方法 调用super final 练习 小结 Override 在继承关系中&#xff0c;子类如果定义了一个与父类方法签名完全相同的方法&#xff0c;被称为覆写&…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

嵌入式常见 CPU 架构

架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集&#xff0c;单周期执行&#xff1b;低功耗、CIP 独立外设&#xff1b;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel&#xff08;原始…...

comfyui 工作流中 图生视频 如何增加视频的长度到5秒

comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗&#xff1f; 在ComfyUI中实现图生视频并延长到5秒&#xff0c;需要结合多个扩展和技巧。以下是完整解决方案&#xff1a; 核心工作流配置&#xff08;24fps下5秒120帧&#xff09; #mermaid-svg-yP…...

​​企业大模型服务合规指南:深度解析备案与登记制度​​

伴随AI技术的爆炸式发展&#xff0c;尤其是大模型&#xff08;LLM&#xff09;在各行各业的深度应用和整合&#xff0c;企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者&#xff0c;还是积极拥抱AI转型的传统企业&#xff0c;在面向公众…...