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

news2025/1/17 23:01:09

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. 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。可以通过引入中介者类来实现,在中介者中定义对象交互的公共行为,如果需要改变行为则可以增加新的具体中介者类。

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

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

相关文章

配置root账户ssh免密登录并使用docker-machine构建docker服务

简介 Docker Machine是一种可以在多种平台上快速安装和维护docker运行环境&#xff0c;并支持多种平台&#xff0c;让用户可以在很短时间内在本地或云环境中搭建一套docker主机集群的工具。 使用docker-machine命令&#xff0c;可以启动、审查、停止、重启托管的docker 也可以…

揭示用户激活的价值:为什么产品经理应该关注

如果你在一家SaaS公司工作&#xff0c;你可能自诩对漏斗指标有很好的理解&#xff0c;你可能可以倒背如流——获取&#xff0c;用户激活&#xff0c;保留&#xff0c;推荐和收入。你甚至可能记得它们的出处&#xff0c;但是你对这些指标的理解到底有多深呢&#xff1f;你知道你…

node.js系列-多种方案教你在node程序中同时使用CommonJS 和 ES Module 混合开发最佳实践

前情提要 我们平时使用的npm 第三方包一般基于这两种规范开发的&#xff0c;很容易遇到一个项目里既有 CommonJS 又有 ES Module 的情况&#xff0c;那么我们应该如何解决这种CommonJS 和 ES Module 混合开发的问题呢&#xff1f; CommonJS是什么&#xff1f; 2009年&#x…

C++学习笔记总结练习--容器

容器 1 简介 新标准库的容器壁使用原始的数组实现的数据结构要快很多。经过了精心的优化。 确定使用哪种容器 除非有明确的理由&#xff0c;否则使用vector随机元素访问vector或deque容器中间插入或者插入元素list、forward_list头尾插入元素&#xff0c;使用deque可以在输入…

RelativeSource有四种类型

Self FindAncestor TemplatedParent PreviousData a.Self Self用于绑定源和绑定目标相同的场景中。对象的一个属性与同一对象的另一个属性绑定。 例如&#xff0c;让我们取一个高度和宽度相同的椭圆。在XAML文件中添加下面给出的代码。宽度属性与高度属性相对绑定。 <G…

Stephen Wolfram:“足够大的网络肯定能做任何事!”

“Surely a Network That’s Big Enough Can Do Anything!” “足够大的网络肯定能做任何事&#xff01;” The capabilities of something like ChatGPT seem so impressive that one might imagine that if one could just “keep going” and train larger and larger neura…

【Kubernetes】Kubernetes的部署

kubernetes 一、Kubernetes 的安装部署1. 常见的安装部署方式1.1 Minikube1.2 Kubeadm1.3 二进制安装部署 2. K8S 部署 二进制与高可用的区别2.1 二进制部署2.2 kubeadm 部署 二、Kubernetes 的部署过程1. 二进制部署1.1 服务器相关设置以及架构1.2 操作系统初始化配置1.3 部署…

【前端|Javascript第1篇】一文搞懂Javascript的基本语法

欢迎来到JavaScript的奇妙世界&#xff01;作为前端开发的基石&#xff0c;JavaScript为网页增色不少&#xff0c;赋予了静态页面活力与交互性。如果你是一名前端小白&#xff0c;对编程一无所知&#xff0c;或者只是听说过JavaScript却从未涉足过&#xff0c;那么你来对了地方…

《探索文心千帆大模型平台: 代码编写从此变得轻松》

文章目录 前言一、初识文心千帆1.1 功能丰富1.2 注册登录 二、内置第三方大模型2.1 ERNIE-Bot模型2.2 ERNIE-Bot-turbo模型2.3 BLOOMZ-7B模型2.4 Llama模型全家桶2.5 在线体验2.5.1 代码编写能力简单提问复杂提问报错解决添加注释 2.5.2 逻辑判断先有鸡还是先有蛋&#xff1f;鸡…

CTF-MISC:BUUCTF练习汇总(26-31题)

CTF-MISC&#xff1a;BUUCTF练习汇总 26、后门查杀27、webshell后门28、来首歌吧29、荷兰宽带数据泄露30、面具下的flag31、九连环 26、后门查杀 解题思路&#xff1a;题干可知webshell的密码为flag&#xff0c;且下载的文件为网站源码&#xff0c;人工查找不太现实&#xff0…

【框架篇】Spring MVC 介绍及使用(详细教程)

Spring MVC 介绍 1&#xff0c;MVC 设计模式 MVC&#xff08;Model-View-Controller&#xff09;是一种常见的软件设计模式&#xff0c;用于将应用程序的逻辑分离成三个独立的组件&#xff1a; 模型&#xff08;Model&#xff09;&#xff1a;模型是应用程序的数据和业务逻辑…

微信小程序iconfont真机渲染失败

解决方法&#xff1a; 1.将下载的.woff文件在transfonter转为base64&#xff0c; 2.打开网站&#xff0c;导入文件&#xff0c;开启base64按钮&#xff0c;下载转换后的文件 3. 在下载解压后的文件夹中找到stylesheet.css&#xff0c;并复制其中的base64 4. 修改index.wxss文…

proj库配置与使用(window11,vs2019,x64)

前置安装依赖 1.SQLite3 安装 亲测 (97条消息) SQLite3源码下载与编译&#xff08;开发环境&#xff1a;Win10VS2022&#xff09;_sqlite3 下载_林夕07的博客-CSDN博客 2.TIFF 亲测 (97条消息) Win11下基于cmake-3.26.3 完美编译 TIFF-4.5.0源码_tiff 编译_GIS子枫的博客-C…

免费的ssl证书

免费的SSL证书对于保证网站的安全性和信任度来说是非常重要的。虽然有些人可能会认为&#xff0c;免费的SSL证书可能不如付费的证书有效&#xff0c;但事实并非如此。 首先&#xff0c;免费的SSL证书同样能够为网站提供加密与解密的功能。这意味着所有的数据将会在传输过程中被…

【雷达通信】非相干多视处理(CSA)(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

[JAVA基础]自动拆装箱NPE问题

1.自动拆装箱场景 自动装箱 当把字面量转换成包装类的时候会自动装箱 比如&#xff1a; Integer a 1; Integer b 1; 自动拆箱 当你对包装类的对象进行运算&#xff08;如加法、减法等&#xff09;时&#xff0c;Java会自动进行拆箱操作。拆箱是将包装类型的对象转换为相应的基…

JavaScript 面向对象

一、对象 1.新建一个对象 // An object literal with two key-value pairs let spaceship {Fuel Type: diesel,color: silver }; We separate each key-value pair in an object literal with a comma (,) Keys are strings, but when we have a key that does not have any…

真人AI写真的制作方法-文生图换脸

AI写真最近火起来了&#xff0c;特别是某款现象级相机的出现&#xff0c;只需要上传自己的照片&#xff0c;就能生成漂亮的写真照&#xff0c;这一产品再次带火了AI绘画。今天我就来分享一个使用Stable Diffusion WebUI制作真人AI写真的方法&#xff0c;不用训练&#xff0c;快…

专家论道: 唐贤香云纱塑造中国非遗国际品牌

自“香云纱染整技艺”入选第二批国家级非物质文化遗产以来&#xff0c;被誉为纺织界“软黄金”的香云纱&#xff0c;重新焕发青春&#xff0c;频频登上时尚舞台&#xff0c;以不一样的面貌展示在世人面前&#xff0c;成为服装设计师、消费者青睐的材质。而随着北京卫视播出的《…