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

中介者模式——协调多个对象之间的交互

1、简介

1.1、概述

如果在一个系统中对象之间的联系呈现为网状结构,如下图所示:
在这里插入图片描述
对象之间存在大量的多对多联系,将导致系统非常复杂,这些对象既会影响别的对象,也会被别的对象所影响,这些对象称为同事对象,它们之间通过彼此的相互作用实现系统的行为。在网状结构中,几乎每个对象都需要与其他对象发生相互作用,而这种相互作用表现为一个对象与另外一个对象的直接耦合,这将导致一个过度耦合的系统。

中介者模式可以使对象之间的关系数量急剧减少。通过引入中介者对象,可以将系统的网状结构变成以中介者为中心的星形结构,如下图所示:
在这里插入图片描述
在这个星形结构中,同事对象不再直接与另一个对象联系,它通过中介者对象与另一个对象发生相互作用。中介者对象的存在保证了对象结构上的稳定,也就是说,系统的结构不会因为新对象的引入带来大量的修改工作。

如果在一个系统中对象之间存在多对多的相互关系,可以将对象之间的一些交互行为从各个对象中分离出来,并集中封装在一个中介者对象中,由该中介者进行统一协调,这样对象之间多对多的复杂关系就转化为相对简单的一对多关系。通过引入中介者来简化对象之间的复杂交互,中介者模式是迪米特法则的一个典型应用。

1.2、定义

中介者模式(Mediator Pattern):用一个中介对象(中介者)来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式,它是一种对象行为型模式。

2、解析

2.1、UML类图

在中介者模式中,引入了用于协调其他对象/类之间相互调用的中介者类。为了让系统具有更好的灵活性和可扩展性,通常还提供了抽象中介者,其结构图如下图所示。
在这里插入图片描述
在中介者模式结构图中包含以下4个角色:

  1. Mediator(抽象中介者):它定义一个接口,该接口用于与各同事对象之间进行通信。
  2. ConcreteMediator(具体中介者):它是抽象中介者的子类,通过协调各个同事对象来实现协作行为,维持了对各个同事对象的引用。
  3. Colleague(抽象同事类):它定义各个同事类公有的方法,并声明了一些抽象方法来供子类实现,同时维持了一个对抽象中介者类的引用,其子类可以通过该引用来与中介者通信。
  4. 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、主要优点

  1. 中介者模式简化了对象之间的交互,它用中介者和同事的一对多交互代替了原来同事之间的多对多交互。一对多关系更容易理解、维护和扩展,将原本难以理解的网状结构转换成相对简单的星形结构。
  2. 中介者模式可将各同事对象解耦。中介者有利于各同事之间的松耦合,可以独立地改变和复用每一个同事和中介者,增加新的中介者和新的同事类都比较方便,更好地符合开闭原则。
  3. 可以减少大量同事子类生成。中介者将原本分布于多个对象间的行为集中在一起,改变这些行为只需要生成新的中介者子类即可,这使得各个同事类可以被重用,无须对同事类进行扩展。

3.2、主要缺点

中介者模式的主要缺点是:在具体中介者类中包含了大量同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。

3.3、适用场景

  1. 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
  2. 一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象。
  3. 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。可以通过引入中介者类来实现,在中介者中定义对象交互的公共行为,如果需要改变行为则可以增加新的具体中介者类。

相关文章:

中介者模式——协调多个对象之间的交互

1、简介 1.1、概述 如果在一个系统中对象之间的联系呈现为网状结构&#xff0c;如下图所示&#xff1a; 对象之间存在大量的多对多联系&#xff0c;将导致系统非常复杂&#xff0c;这些对象既会影响别的对象&#xff0c;也会被别的对象所影响&#xff0c;这些对象称为同事对…...

启动Flink显示初始化状态怎么解决?

启动Flink显示初始化状态怎么解决&#xff1f; Flink On Yarn模式 问题 flnk任务在跑的过程中&#xff0c; 有时候任务停掉了 &#xff0c;不过我有 定时任务&#xff0c;可以把失败的flink任务拉起来&#xff0c;但是因为最新的checkpoint做失败了&#xff0c;导致脚本无法拉…...

VB+SQL采购管理系统设计与实现

摘 要 本系统是基于为轴承企业采购部门开发的系统。课题主要采用自上而下的结构化程序设计方法与面向对象方法相结合的方法,致力于达到标准的现代化物流管理要求。帮助轴承企业采购部门全面实现电子化、自动化、标准化的现代化先进管理模式。 该系统使用Visualbasic.net编程…...

TBB库中实现协程(coroutine)的源码说明

源码请见: https://github.com/oneapi-src/oneTBB/blob/master/src/tbb/co_context.h 在windows系统&#xff0c;TBB(也就是intel 的 oneTBB库)&#xff0c;通过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开发&#xff0c;却并没有什么成长&#xff0c;都停留在了业务层面了。一直以为golang中函数传参&#xff0c;如果传的是引用类型&#xff0c;则是以引用传递&#xff0c;造成这样的误解&#xff0c;实在也不能怪我。我们来看一个例子&#xff0c;众所周知&#xf…...

Liunx环境下git的详细使用(gitee版)

Liunx环境下git的详细使用&#xff08;gitee版&#xff09; 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函数&#xff0c; Number&#xff08;param&#xff09; 1-1. param 是 原始类型 时 数值&#xff1a;转换后还是原来的值 字符串&#xff1a;如果可以被解析…...

【云原生】 一文了解docker中的网络

文章目录 1.在Docker中,网络的实现方式是通过使用不同的网络驱动程序来实现的。2.桥接网络是默认网络。3.主机网络模式是不使用网络隔离的一种特殊模式。4.另一个有用的网络驱动程序是覆盖网络。5.最后,MACVLAN网络驱动程序允许多个容器与宿主机网卡的单独MAC地址和IP地址之间…...

嵌入式开发学习(STC51-15-红外遥控)

内容 使用外部中断功能&#xff0c;使按下红外遥控器&#xff0c;将对应键值编码数据解码后通过数码管显示 红外遥控介绍 红外线简介 人的眼睛能看到的可见光按波长从长到短排列&#xff0c;依次为红、橙、黄、绿、青、蓝、紫&#xff1b; 其中红光的波长范围为 0.62&…...

代码编辑器实践之vue-codemirror使用

前言 程序员用到IDE次数比较频繁&#xff0c;比如vscode、idea等&#xff0c;这些都是市场上比较流行的代码编辑器&#xff0c;拥有非常全面的功能。但是有时候在项目开发上也会用到代码编辑器&#xff0c;比如复杂的Array<Object>输入&#xff0c;或者需要用到用户交互…...

Mapstruct

1. Mapstruct介绍 1. 实体类之间对象映射中间件 2. 实体类相同结构属性自动对象映射 3. 实体类不同结构属性可以手动配置对象映射 2. Mapstruct基本使用 1. 定义一个接口或抽象类加Mapper(componentModel “spring”)&#xff1b;spring&#xff1a;可以spring框架注入 2. 定义…...

初阶C语言——特别详细地介绍函数

系列文章目录 第一章 “C“浒传——初识C语言&#xff08;更适合初学者体质哦&#xff01;&#xff09; 第二章 详细认识分支语句和循环语句以及他们的易错点 第三章 初阶C语言——特别详细地介绍函数 目录 系列文章目录 前言 一、函数是个什么鬼东西&#xff1f; 二、C语…...

pulsar-client-1-2 PulsarClient构造函数

前言 上文说到,PulsarClient通过链式调用构建,而在build()中调用了new PulsarClientImpl(conf),而Producer 本文通过解析构造函数,了解其主要结构。 // 创建PulsarClient PulsarClient client = PulsarClient.builder().serviceUrl("pulsar://localhost:6650")…...

原型链污染是什么

__proto__ 一个Foo类实例化出来的foo对象&#xff0c;可以通过foo.__proto__属性来访问Foo类的原型&#xff0c;也就是说&#xff1a; foo.__proto__ Foo.prototype 对象 构造函数 所以&#xff0c;总结一下&#xff1a; prototype是一个类的属性&#xff0c;所有…...

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 系列&#xff08;含 Debian 12、基于 Debian 12 的Proxmox 8.0-2 以及基于Debian 11 的 openm…...

IP路由基础+OSPF 基础

IP路由 RIB与FIB RIB&#xff1a;Routing Information Base&#xff0c;路由信息库 &#xff0c;路由器的控制平面 FIB&#xff1a;Forwarding Information Base&#xff0c;转发信息库&#xff0c;路由器的数据平面 路由信息库主要是记录直连路由以及协议宣告的路由信息&am…...

window远程连接Linux

Linux启用ssh服务 管理员权限进入root 安装 OpenSSH 服务器软件包 对于 Debian、Ubuntu 或基于这些发行版的系统&#xff0c;可以运行以下命令安装&#xff1a; sudo apt update sudo apt install openssh-server对于基于 Red Hat、CentOS 或 Fedora 的系统&#xff0c;可以…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...

轻量级Docker管理工具Docker Switchboard

简介 什么是 Docker Switchboard &#xff1f; Docker Switchboard 是一个轻量级的 Web 应用程序&#xff0c;用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器&#xff0c;使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...

深度解析:etcd 在 Milvus 向量数据库中的关键作用

目录 &#x1f680; 深度解析&#xff1a;etcd 在 Milvus 向量数据库中的关键作用 &#x1f4a1; 什么是 etcd&#xff1f; &#x1f9e0; Milvus 架构简介 &#x1f4e6; etcd 在 Milvus 中的核心作用 &#x1f527; 实际工作流程示意 ⚠️ 如果 etcd 出现问题会怎样&am…...

持续交付的进化:从DevOps到AI驱动的IT新动能

文章目录 一、持续交付的本质&#xff1a;从手动到自动的交付飞跃关键特性案例&#xff1a;电商平台的高效部署 二、持续交付的演进&#xff1a;从CI到AI驱动的未来发展历程 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/101f72defaf3493ba0ba376bf09367a2.png)中国…...

spring中的@KafkaListener 注解详解

KafkaListener 是 Spring Kafka 提供的一个核心注解&#xff0c;用于标记一个方法作为 Kafka 消息的消费者。下面是对该注解的详细解析&#xff1a; 基本用法 KafkaListener(topics "myTopic", groupId "myGroup") public void listen(String message)…...

leetcode238-除自身以外数组的乘积

leetcode 238 思路 可以在不使用除法的情况下&#xff0c;利用前缀积和后缀积来实现解答 前缀积&#xff1a;对每个位置&#xff0c;计算当前数字左侧的所有数字的乘积后缀积&#xff1a;对每个位置&#xff0c;计算当前数字右侧的所有数字的乘积 结合这两种思想&#xff0…...