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

news2025/2/26 5:20:44
  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_sec
	m_sec->initcountry(country_usa,country_iraq);


	m_sec->delcare("我要干死你" , country_usa);
	m_sec->delcare("来呀,cnm,互相伤害呀" , country_iraq);


	cout<<endl<<endl;
	return 0;
}

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

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

相关文章

无人机双目视觉鲁棒定位方法!

无人机双目视觉鲁棒定位方法是一种先进的定位技术&#xff0c;它利用两个摄像头&#xff08;即双目相机&#xff09;模拟人的视觉系统&#xff0c;通过视差来确定物体的位置。这种方法在无人机定位领域具有广泛的应用前景&#xff0c;特别是在GPS信号拒止或弱纹理环境中&#x…

【R语言遥感技术】“R+遥感”的水环境综合评价方法

R语言在遥感领域中是一个强大的工具&#xff0c;它提供了一系列的功能和优势&#xff0c;使得遥感数据的分析和应用更加高效和灵活。以下是R语言在遥感中的具体应用&#xff1a; 数据处理&#xff1a;R语言可以处理和清洗遥感数据&#xff0c;包括数据转换、滤波处理、去噪和数…

vue预览和下载 pdf、ppt、word、excel文档,文件类型为链接或者base64格式或者文件流,

** 方法1&#xff1a;word、xls、ppt、pdf 这些文件&#xff0c; 如果预览的文件是链接可以直接打开&#xff0c;可用微软官方的预览地址 ** <iframe width"100%" :src"textVisibleURl " id"myFramePPT" style"border: none;backgroun…

无人设备遥控器之定向天线篇

一、定义与功能 定向天线&#xff0c;顾名思义&#xff0c;是通过改变天线的辐射方向&#xff0c;实现信号发射、接收和增强的天线。它可以让信号以更高的功率、更远的距离传输到指定区域&#xff0c;同时也能够降低与周围天线之间的干扰。在无人设备遥控器中&#xff0c;定向天…

什么是Redis缓存击穿?如何解决

1.缓存击穿介绍 Redis的缓存击穿指的是在高并发场景下&#xff0c;当一个被大量请求访问的热点key&#xff08;即非常热门的数据项&#xff09;在Redis中过期时&#xff0c;所有请求几乎同时发现缓存失效并尝试直接从后端数据库读取数据&#xff0c;这可能会导致瞬间大量的数据…

Qt父窗口处理子窗口大小变化消息installEventFilter

1.需求描述 父窗口从上到下时标题栏&#xff0c;播放窗口和工具栏&#xff0c;希望监测中间播放窗口的大小变化&#xff0c;来根据分辨率自动调整播放画面的宽高&#xff1b;因为工具栏和标题栏可以隐藏&#xff0c;所以父窗口大小不变&#xff0c;中间的播放窗口也会随着工具…

HiQA: A Hierarchical Contextual Augmentation RAG for Multi-Documents QA---附录

附录 建议的问答系统 在建议的框架中&#xff0c;问答过程是单步的。首先&#xff0c;根据查询使用 RAG 从文档库中检索相关知识。随后&#xff0c;将此上下文与问题一起输入到语言模型中以生成响应。返回答案的第一个字符所需的时间在 1 到 3 秒之间。图 5 显示了 QA 流程的…

MoGe---最新单目3D几何估计方法

目录 一、概述 二、相关工作 1、单目深度估计 2、单目几何估计 3、相机内参估计 4、单目几何的大规模数据训练 三、前置知识 1、仿射不变和尺度不变指标 2、FOV和shift 3、ROE对齐求解器 四、MoGe 1、为什么设计仿射不变&#xff1f; 2、恢复相机焦距和移位 3、…

Jenkins安全部署规范及安全基线

Jenkins安全部署规范及安全基线 进入安全设置界面启用安全Disable remember me访问控制——安全域&#xff08;Security Realm&#xff09;servlet容器代理&#xff08;Delegate to servlet container&#xff09;Jenkins专有用户数据库&#xff08;Jenkins’ own user databas…

写SQL太麻烦?免费搭建 Text2SQL 应用,智能写 SQL | OceanBase AI 实践

自OceanBase 4.3.3版本推出以来&#xff0c;向量检索的能力受到了很多客户的关注&#xff0c;也纷纷表达希望OB能拓展更多 多模数据库大模型 的AI应用实践。 在上篇文章 &#x1f449; OceanBase LLM&#xff0c;免费构建你的专属 AI 助手 &#xff0c;我们介绍了如何去搭建一…

5.npm包

文章目录 [TOC](文章目录) 3.npm与包3.1.包3.2.npm体验在项目中安装包的命令包管理配置文件一次性安装开发项目时安装的包如何从项目中卸载包devDependencies节点的作用解决下载包速度比较慢的问题nrm工具&#xff0c;利用其提供的终端命令&#xff0c;可以快速查看和切换下包的…

Dots 常用操作

游戏中有多个蚂蚁群落&#xff0c;每个蚂蚁属于一个群落&#xff0c;如何设计数据结构&#xff1f; 方法1&#xff1a;为蚂蚁组件添加一个属性 ID&#xff0c;会造成逻辑中大量分支语句&#xff0c;如果分支语句逻辑不平衡可能带来 Job 调度问题&#xff0c;每个蚂蚁会有一份蚂…

HTML与数据抓取:GET与POST方法详解

讲GET和POST就不能只讲GET和POST 你要讲HTTP请求的基本概念&#xff1a; HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是互联网上应用最为广泛的一种网络协议&#xff0c;主要用于Web浏览器与Web服务器之间的数据通信。HTTP是一个基于…

Android 之 Activity 的启动模式(launchMode)

一、Activity 启动模式 在实际项目中&#xff0c;应该根据项目的实际需要来为每个 Activity 指定恰当的启动模式 launchMode。启动模式一共有四种&#xff0c;分别是 standard、singleTop、singleTask 和 singleInstance。可以在 AndroidManifest.xml 中通过给 <activity&g…

软考:系统架构设计师教材笔记(持续更新中)

教材中的知识点都会在。其实就是将教材中的废话删除&#xff0c;语言精练一下&#xff0c;内容比较多&#xff0c;没有标注重点 系统架构概述 定义 系统是指完成某一特定功能或一组功能所需要的组件集&#xff0c;而系统架构则是对所有组件的高层次结构表示&#xff0c;包括各…

大模型应用—IOPaint 图片去水印

IOPaint 是由 SOTA AI 模型提供支持的免费开源修复和修复工具,可以轻松实现图片去水印,去除图片不需要的部分,是目前效果最好的一个项目!完全免费开源 IOPaint 已经托管到 hugging face上,打开就可以直接免费使用,需要外网环境! 在线免费使用:【链接直达】 如果你需要…

Go C编程 第6课 无人机 --- 计算旋转角

旋转的秘密---认识角度 rt、lt命令学习 goc电子课程 一、编程步骤 第一步 第二步 第三步 第四步 二、画“四轴无人机” &#xff08;一&#xff09;、画第一根机轴 &#xff08;二&#xff09;、画第二根机轴 &#xff08;三&#xff09;、画完整的无人机 三、画“多轴无人…

v3s点RGB屏 40pin 800x480,不一样的点屏,不通过chosen。

一、背景、目的、简介。 一般来说&#xff0c;通过uboot将屏幕参数传给kernel&#xff0c;是通过修改设备树。 uboot和kernel都需要屏幕点亮。uboot侧重于显示一张图片。而kernel则多是动画。 在这里&#xff0c;我先是找到了一个裸机点屏的代码。将其编译成静态库后&#x…

【编译原理】编译原理知识点汇总·语法分析器(消除左递归、消除二义性、自顶向下语法分析、自下向上语法分析)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;编译原理_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2. …

golang 并发--goroutine(四)

golang 语言最大的特点之一就是语法上支持并发&#xff0c;通过简单的语法很容易就能创建一个 go 程&#xff0c;这就使得 golang 天生适合写高并发的程序。这一章节我们就主要介绍 go 程&#xff0c;但是要想完全理解 go 程我们需要深入研究 GPM 模型&#xff0c;关于 GPM 模型…