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

  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;
}

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

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

相关文章

Redis篇--常见问题篇7--缓存一致性2(分布式事务框架Seata)

1、概述 在传统的单体应用中&#xff0c;事务管理相对简单&#xff0c;通常使用数据库的本地事务&#xff08;如MySQL的BEGIN和COMMIT&#xff09;来保证数据的一致性。然而&#xff0c;在微服务架构中&#xff0c;由于每个服务都有自己的数据库&#xff0c;跨服务的事务管理变…

如何评估一个股票API接口

评估一个股票 API 接口的质量&#xff0c;可以从以下几个方面进行&#xff1a; 数据准确性 行情数据&#xff1a;实时价格、历史价格、成交量、成交额等数据应与证券交易所或权威金融数据提供商的官方数据高度一致&#xff0c;确保没有明显的错误。财务数据&#xff1a;企业的…

某集团GIF动态验证码识别

注意&#xff0c;本文只提供学习的思路&#xff0c;严禁违反法律以及破坏信息系统等行为&#xff0c;本文只提供思路 如有侵犯&#xff0c;请联系作者下架 本文识别已同步上线至OCR识别网站&#xff1a; http://yxlocr.nat300.top/ocr/other/16 最近某集团更新了验证码&#x…

数据库系统原理:数据恢复与备份策略

3.1可行性分析 开发者在进行开发系统之前&#xff0c;都需要进行可行性分析&#xff0c;保证该系统能够被成功开发出来。 3.1.1技术可行性 开发该《数据库系统原理》课程平台所采用的技术是vue和MYSQL数据库。计算机专业的学生在学校期间已经比较系统的学习了很多编程方面的知识…

CPU算法分析LiteAIServer裸土检测算法如何应用在农田科学管理中?

农田是农业生产的基础&#xff0c;是保障国家粮食安全和农业可持续发展的关键。随着人口增长和城市化进程的加快&#xff0c;农田保护和治理面临着前所未有的挑战。如今农田土壤依旧面临着巨大挑战&#xff1a; 1、‌土壤侵蚀‌&#xff1a;长期的风蚀、水蚀等自然因素&#x…

Marscode AI辅助编程

直接使用Marscode的云服务来开发&#xff0c;也是很方便的&#xff0c;不用担心配置环境的问题&#xff0c;很适合初步学习&#xff0c;在任何设备都能开发。 番茄钟 请你基于html、tailwind css和javascript&#xff0c;帮我设计一个“番茄时钟”。要求UI简洁美观大方&#x…

Debian 12 安装配置 fail2ban 保护 SSH 访问

背景介绍 双十一的时候薅羊毛租了台腾讯云的虚机, 是真便宜, 只是没想到才跑了一个月, 系统里面就收集到了巨多的 SSH 恶意登录失败记录. 只能说, 互联网真的是太不安全了. 之前有用过 fail2ban 在 CentOS 7 上面做过防护, 不过那已经是好久好久之前的故事了, 好多方法已经不…

idea2024创建JavaWeb项目以及配置Tomcat详解

今天呢&#xff0c;博主的学习进度也是步入了JavaWeb&#xff0c;目前正在逐步杨帆旗航&#xff0c;迎接全新的狂潮海浪。 那么接下来就给大家出一期有关JavaWeb的配置教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正…

Canoe E2E校验自定义Checksum算法

文章目录 一、添加 DBC文件二、导入要仿真的ECU节点三、编写 CAPL脚本1. 创建 .can 文件2. 设置counter递增3. 设置 CRC 算法&#xff0c;以profile01 8-bit SAE J1850 CRC校验为例 四、开始仿真五、运行结果CRC在线校验 当E2E的 CRC算法非常规算法&#xff0c;则需要自己编写代…

PyTorch 神经网络回归(Regression)任务:关系拟合与优化过程

PyTorch 神经网络回归&#xff08;Regression&#xff09;任务&#xff1a;关系拟合与优化过程 本教程介绍了如何使用 PyTorch 构建一个简单的神经网络来实现关系拟合&#xff0c;具体演示了从数据准备到模型训练和可视化的完整过程。首先&#xff0c;利用一维线性空间生成带噪…

【uni-app】2025最新uni-app一键登录保姆级教程(包含前后端获取手机号方法)(超强避坑指南)

前言&#xff1a; 最近在配置uni-app一键登录时遇到了不少坑&#xff0c;uni-app的配套文档较为混乱&#xff0c;并且有部分更新的内容也没有及时更改在文档上&#xff0c;导致部分开发者跟着uni-app配套文档踩坑&#xff01;而目前市面上的文章质量也层次不齐&#xff0c;有的…

干货分享:ISO 20000认证的适用范围、认证资料清单、认证流程等问题详解

编辑&#xff1a;石芸姗 审核&#xff1a;贺兆普 在当今这个数字化时代&#xff0c;信息技术&#xff08;IT&#xff09;已成为企业运营与发展的核心驱动力。随着技术的不断进步和业务需求的日益复杂&#xff0c;企业对IT服务的质量、效率及安全性提出了更高要求。 信息技术服…

Element-plus表格使用总结

这里我使用的是Vue工程进行开发学习&#xff0c;安装需要通过包管理器进行下载 npm install element-plus --save 然后在main.js中配置文件即可使用&#xff0c;如果在引入index.css时没有提示&#xff0c;无需担心&#xff0c;直接写index.css即可导入样式。 Table表格 表格…

CNN和Transfomer介绍

文章目录 CNN和Transfomer介绍CNN和Transfomer的区别1. **基本概念**2. **数据处理方式**3. **模型结构差异**4. **应用场景区别** 自注意力机制1. **自注意力机制的概念**2. **自注意力机制的实现步骤**3. **自注意力机制的优势** Transformer结构组成1. **多头注意力层&#…

如何解决 ‘adb‘ 不是内部或外部命令,也不是可运行的程序或批处理文件的问题

在cmd中输入 adb &#xff0c;显示 ‘adc‘ 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件的问题 解决办法&#xff1a;在环境变量中添加adb所在的路径 1、找到 adb.exe 的所在的文件路径&#xff0c;一般在 Android 安装目录下 \sdk\platform-tools\adb.exe…

数据结构---------二叉树前序遍历中序遍历后序遍历

以下是用C语言实现二叉树的前序遍历、中序遍历和后序遍历的代码示例&#xff0c;包括递归和非递归&#xff08;借助栈实现&#xff09;两种方式&#xff1a; 1. 二叉树节点结构体定义 #include <stdio.h> #include <stdlib.h>// 二叉树节点结构体 typedef struct…

网络架构与IP技术:4K/IP演播室制作的关键支撑

随着科技的不断发展&#xff0c;广播电视行业也在不断迭代更新&#xff0c;其中4K/IP演播室技术的应用成了一个引人注目的焦点。4K超高清技术和IP网络技术的结合&#xff0c;不仅提升了节目制作的画质和效果&#xff0c;还为节目制作带来了更高的效率和灵活性。那么4K超高清技术…

MySQL 8.0:explain analyze 分析 SQL 执行过程

介绍 MySQL 8.0.16 引入一个实验特性&#xff1a;explain formattree &#xff0c;树状的输出执行过程&#xff0c;以及预估成本和预估返 回行数。在 MySQL 8.0.18 又引入了 EXPLAIN ANALYZE&#xff0c;在 formattree 基础上&#xff0c;使用时&#xff0c;会执行 SQL &#…

观察者模式(sigslot in C++)

大家&#xff0c;我是东风&#xff0c;今天抽点时间整理一下我很久前关注的一个不错的库&#xff0c;可以支持我们在使用标准C的时候使用信号槽机制进行观察者模式设计&#xff0c;sigslot 官网&#xff1a; http://sigslot.sourceforge.net/ 本文较为详尽探讨了一种观察者模…

【已解决】黑马点评项目Redis版本替换过程中误删数据库后前端显示出现的问题

为了实现基于Redis的Stream结构作为消息队列&#xff0c;实现异步秒杀下单的功能&#xff0c;换Redis版本 Redis版本太旧了&#xff0c;所以从3.2.1换成了5.0.14 此时犯了一个大忌&#xff0c;因为新的Redis打开后&#xff0c;没有缓存&#xff0c;不知道出了什么问题&#xf…