中介者模式——协调多个对象之间的交互
1、简介
1.1、概述
如果在一个系统中对象之间的联系呈现为网状结构,如下图所示:
对象之间存在大量的多对多联系,将导致系统非常复杂,这些对象既会影响别的对象,也会被别的对象所影响,这些对象称为同事对象,它们之间通过彼此的相互作用实现系统的行为。在网状结构中,几乎每个对象都需要与其他对象发生相互作用,而这种相互作用表现为一个对象与另外一个对象的直接耦合,这将导致一个过度耦合的系统。
中介者模式可以使对象之间的关系数量急剧减少。通过引入中介者对象,可以将系统的网状结构变成以中介者为中心的星形结构,如下图所示:
在这个星形结构中,同事对象不再直接与另一个对象联系,它通过中介者对象与另一个对象发生相互作用。中介者对象的存在保证了对象结构上的稳定,也就是说,系统的结构不会因为新对象的引入带来大量的修改工作。
如果在一个系统中对象之间存在多对多的相互关系,可以将对象之间的一些交互行为从各个对象中分离出来,并集中封装在一个中介者对象中,由该中介者进行统一协调,这样对象之间多对多的复杂关系就转化为相对简单的一对多关系。通过引入中介者来简化对象之间的复杂交互,中介者模式是迪米特法则的一个典型应用。
1.2、定义
中介者模式(Mediator Pattern):用一个中介对象(中介者)来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式,它是一种对象行为型模式。
2、解析
2.1、UML类图
在中介者模式中,引入了用于协调其他对象/类之间相互调用的中介者类。为了让系统具有更好的灵活性和可扩展性,通常还提供了抽象中介者,其结构图如下图所示。
在中介者模式结构图中包含以下4个角色:
- Mediator(抽象中介者):它定义一个接口,该接口用于与各同事对象之间进行通信。
- ConcreteMediator(具体中介者):它是抽象中介者的子类,通过协调各个同事对象来实现协作行为,维持了对各个同事对象的引用。
- Colleague(抽象同事类):它定义各个同事类公有的方法,并声明了一些抽象方法来供子类实现,同时维持了一个对抽象中介者类的引用,其子类可以通过该引用来与中介者通信。
- ConcreteColleague(具体同事类):它是抽象同事类的子类。每一个同事对象在需要和其他同事对象通信时,先与中介者通信,通过中介者来间接完成与其他同事类的通信。在具体同事类中实现了在抽象同事类中声明的抽象方法。
中介者模式的核心在于中介者类的引入。在中介者模式中,中介者类承担了以下两方面的职责:
(1)中转作用(结构性)。通过中介者提供的中转作用,各个同事对象就不再需要显式地引用其他同事。当需要和其他同事进行通信时,可通过中介者来实现间接调用。该中转作用属于中介者在结构上的支持。
(2)协调作用(行为性)。中介者可以更进一步地对同事之间的关系进行封装,同事可以一致地和中介者进行交互,而不需要指明中介者需要具体怎么做。中介者根据封装在自身内部的协调逻辑,对同事的请求进行进一步处理,将同事成员之间的关系行为进行分离和封装。该协调作用属于中介者在行为上的支持。
2.2、代码示例
在中介者模式中,典型的抽象中介者类代码如下:
/*** @Description: 抽象中介者* @Author: yangyongbing* @CreateTime: 2023/08/03 08:56* @Version: 1.0*/
public class Mediator {// 存储同事对象protected ArrayList<Colleague> colleagues;// 注册方法,用于增加同事对象public void register(Colleague colleague){colleagues.add(colleague);}// 声明抽象的业务方法public void operation() {}
}
在抽象中介者中可以定义一个同事类的集合,用于存储同事对象并提供注册方法,同时声明具体中介者类所具有的方法。在具体中介者类中将实现这些抽象方法,典型的具体中介者类代码如下:
/*** @Description: 具体中介者* @Author: yangyongbing* @CreateTime: 2023/08/03 08:58* @Version: 1.0*/
public class ConcreteMediator extends Mediator{// 实现业务方法,封装同事之间的调用public void operation(){// 通过中介者调用同事类的方法colleagues.get(0).method();}
}
在具体中介者类中将调用同事类的方法,调用时可以增加一些自己的业务代码对调用进行控制。
在抽象同事类中维持了一个抽象中介者的引用,用于调用中介者的方法。典型的抽象同事类代码如下:
/*** @Description: 抽象同事类* @Author: yangyongbing* @CreateTime: 2023/08/03 09:02* @Version: 1.0*/
public class Colleague {// 维持一个抽象中介者的引用protected Mediator mediator;public Colleague(Mediator mediator) {this.mediator = mediator;}// 声明自身方法,处理自己的行为public void method() {}// 定义依赖方法,与中介者进行通信public void dependencyMethod(){mediator.operation();}
}
在抽象同事类中声明了同事类的抽象方法,而在具体同事类中将实现这些方法。典型的具体同事类代码如下:
/*** @Description: 具体同事类* @Author: yangyongbing* @CreateTime: 2023/08/03 09:06* @Version: 1.0*/
public class ConcreteColleague extends Colleague{public ConcreteColleague(Mediator mediator) {super(mediator);}// 实现自身方法public void method(){}
}
在具体同事类ConcreteColleague中实现了在抽象同事类中声明的方法。其中方法method()是同事类的自身方法(Self-Method),用于处理自己的行为。方法dependencyMethod()是依赖方法(Depend-Method),用于调用在中介者中定义的方法,依赖中介者来完成相应的行为,例如调用另一个同事类的相关方法。
3、中介者模式总结
中介者模式将一个网状的系统结构变成一个以中介者对象为中心的星形结构。在这个星形结构中,使用中介者对象与其他对象的一对多关系来取代原有对象之间的多对多关系。中介者模式在事件驱动类软件中应用较为广泛,特别是基于GUI的应用软件。此外,在类与类之间存在错综复杂的关联关系的系统中,中介者模式都得到了较好的应用。
3.1、主要优点
- 中介者模式简化了对象之间的交互,它用中介者和同事的一对多交互代替了原来同事之间的多对多交互。一对多关系更容易理解、维护和扩展,将原本难以理解的网状结构转换成相对简单的星形结构。
- 中介者模式可将各同事对象解耦。中介者有利于各同事之间的松耦合,可以独立地改变和复用每一个同事和中介者,增加新的中介者和新的同事类都比较方便,更好地符合开闭原则。
- 可以减少大量同事子类生成。中介者将原本分布于多个对象间的行为集中在一起,改变这些行为只需要生成新的中介者子类即可,这使得各个同事类可以被重用,无须对同事类进行扩展。
3.2、主要缺点
中介者模式的主要缺点是:在具体中介者类中包含了大量同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。
3.3、适用场景
- 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
- 一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象。
- 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。可以通过引入中介者类来实现,在中介者中定义对象交互的公共行为,如果需要改变行为则可以增加新的具体中介者类。
相关文章:

中介者模式——协调多个对象之间的交互
1、简介 1.1、概述 如果在一个系统中对象之间的联系呈现为网状结构,如下图所示: 对象之间存在大量的多对多联系,将导致系统非常复杂,这些对象既会影响别的对象,也会被别的对象所影响,这些对象称为同事对…...

启动Flink显示初始化状态怎么解决?
启动Flink显示初始化状态怎么解决? Flink On Yarn模式 问题 flnk任务在跑的过程中, 有时候任务停掉了 ,不过我有 定时任务,可以把失败的flink任务拉起来,但是因为最新的checkpoint做失败了,导致脚本无法拉…...
VB+SQL采购管理系统设计与实现
摘 要 本系统是基于为轴承企业采购部门开发的系统。课题主要采用自上而下的结构化程序设计方法与面向对象方法相结合的方法,致力于达到标准的现代化物流管理要求。帮助轴承企业采购部门全面实现电子化、自动化、标准化的现代化先进管理模式。 该系统使用Visualbasic.net编程…...

TBB库中实现协程(coroutine)的源码说明
源码请见: https://github.com/oneapi-src/oneTBB/blob/master/src/tbb/co_context.h 在windows系统,TBB(也就是intel 的 oneTBB库),通过windwos fiber(纤程)来实现协程(coroutine)。 创建一个协程,代码很简洁: inline void create_coroutine(corouti…...
【CSS弹性盒模型 display:flex;常用参数及常见的布局】
CSS弹性盒模型 display:flex;常用参数flex-directionjustify-contentalign-itemsflex-wrapflex-flowalign-contentorderflex-growflex-shrinkflex-basis 常见的布局1. 水平居中2. 垂直居中3. 水平垂直居中4. 等分布局5. 响应式布局6. 网格布局 常见的布局封装 display:flex;常用…...

golang函数传参——值传递理解
做了五年的go开发,却并没有什么成长,都停留在了业务层面了。一直以为golang中函数传参,如果传的是引用类型,则是以引用传递,造成这样的误解,实在也不能怪我。我们来看一个例子,众所周知…...

Liunx环境下git的详细使用(gitee版)
Liunx环境下git的详细使用(gitee版) 1.git是什么2.git操作2.1在gitee创建一个仓库2.2.gitignore2.3.git 3.git三板斧3.1add3.2 commit3.3push 4.git其他命令4.1查看当前仓库状态4.2查看提交日志4.3修改git里面文件名称4.4删除文件4.5修改远端仓库内容 1.…...
exoplayer的使用-2,与flutter相互通信
上一次解决的问题是ac3这些exoplayer本身不支持音频,添加了ffmpeg扩展实现软解码. 另一个问题是flutter端的内置字幕显示不了,也不打算再继续探讨了,换成native实现播放器.由于主项目是flutter的,所以涉及到了相互通信. 当前文章主要涉及到flutter与native相互通信功能 通信有…...
【基础类】—类型转换
一、数据类型 原始类型 Boolean、Null、Undefined、Number、String、Symbol 对象 Object 二、显示类型转换 Number函数, Number(param) 1-1. param 是 原始类型 时 数值:转换后还是原来的值 字符串:如果可以被解析…...
【云原生】 一文了解docker中的网络
文章目录 1.在Docker中,网络的实现方式是通过使用不同的网络驱动程序来实现的。2.桥接网络是默认网络。3.主机网络模式是不使用网络隔离的一种特殊模式。4.另一个有用的网络驱动程序是覆盖网络。5.最后,MACVLAN网络驱动程序允许多个容器与宿主机网卡的单独MAC地址和IP地址之间…...

嵌入式开发学习(STC51-15-红外遥控)
内容 使用外部中断功能,使按下红外遥控器,将对应键值编码数据解码后通过数码管显示 红外遥控介绍 红外线简介 人的眼睛能看到的可见光按波长从长到短排列,依次为红、橙、黄、绿、青、蓝、紫; 其中红光的波长范围为 0.62&…...
代码编辑器实践之vue-codemirror使用
前言 程序员用到IDE次数比较频繁,比如vscode、idea等,这些都是市场上比较流行的代码编辑器,拥有非常全面的功能。但是有时候在项目开发上也会用到代码编辑器,比如复杂的Array<Object>输入,或者需要用到用户交互…...
Mapstruct
1. Mapstruct介绍 1. 实体类之间对象映射中间件 2. 实体类相同结构属性自动对象映射 3. 实体类不同结构属性可以手动配置对象映射 2. Mapstruct基本使用 1. 定义一个接口或抽象类加Mapper(componentModel “spring”);spring:可以spring框架注入 2. 定义…...

初阶C语言——特别详细地介绍函数
系列文章目录 第一章 “C“浒传——初识C语言(更适合初学者体质哦!) 第二章 详细认识分支语句和循环语句以及他们的易错点 第三章 初阶C语言——特别详细地介绍函数 目录 系列文章目录 前言 一、函数是个什么鬼东西? 二、C语…...
pulsar-client-1-2 PulsarClient构造函数
前言 上文说到,PulsarClient通过链式调用构建,而在build()中调用了new PulsarClientImpl(conf),而Producer 本文通过解析构造函数,了解其主要结构。 // 创建PulsarClient PulsarClient client = PulsarClient.builder().serviceUrl("pulsar://localhost:6650")…...
原型链污染是什么
__proto__ 一个Foo类实例化出来的foo对象,可以通过foo.__proto__属性来访问Foo类的原型,也就是说: foo.__proto__ Foo.prototype 对象 构造函数 所以,总结一下: prototype是一个类的属性,所有…...
java之石头迷阵单击游戏、继承、接口、窗体、事件、组件、按钮、图片
文章目录 前言主方法实现类 前言 主方法和实现类在同一个包中。 主方法 package PSortGames;public class Main {public static void main(String[] args) {new MainFrame();} }实现类 package PSortGames;import javax.swing.*; import java.awt.event.KeyEvent; import jav…...
Debian 系列 Linux 的静态 DNS 、gateway 、IP 设置和网络重启
文章目录 DNS 设置DNS 配置文件DNS 配置文件内容 gateway、IP 设置网络适配器配置文件网络适配器配置文件内容 网络重启 各个 Linux 发行版的网络设置有很大不同。根据最近对 Debian 系列(含 Debian 12、基于 Debian 12 的Proxmox 8.0-2 以及基于Debian 11 的 openm…...

IP路由基础+OSPF 基础
IP路由 RIB与FIB RIB:Routing Information Base,路由信息库 ,路由器的控制平面 FIB:Forwarding Information Base,转发信息库,路由器的数据平面 路由信息库主要是记录直连路由以及协议宣告的路由信息&am…...
window远程连接Linux
Linux启用ssh服务 管理员权限进入root 安装 OpenSSH 服务器软件包 对于 Debian、Ubuntu 或基于这些发行版的系统,可以运行以下命令安装: sudo apt update sudo apt install openssh-server对于基于 Red Hat、CentOS 或 Fedora 的系统,可以…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...