当前位置: 首页 > 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;被称为覆写&…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...