19、设计模式之中介者模式(Mediator)

news2024/12/23 3:26:41

一、什么是中介者模式
中介者模式是一种行为型设计模式,它用于减少对象之间互相通信的复杂性。中介者模式通过创建一个中介者对象,将对象之间的通信集中交给该对象来处理,而不是直接相互交流,是符合迪米特原则的典型应用。
迪米特原则:减少对象之间的依赖,即一个对象应当对其它对象有尽可能少的了解

二、角色组成

抽象中介者(Mediator):用于协调各个同事对象之间交互的通用接口,如接收和发送消息等。 具体中介者(Concrete
Mediator):实现抽象中介者接口,定义一个List来管理同时对象,协调各个同事对象之间的交互,依赖于同事角色。
抽象同事类(Colleague):保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
具体同事类(Concrete
Colleague):实现抽象同事类接口,当需要与其他同事对象交互时,由中介者对象负责后续的交互,简单地说就是维护和中介者对象的通信。

三、优缺点
优点:

减少对象之间的耦合度,使其变得简单易维护。
提高代码的重用性和可扩展性,增强了系统的灵活性和可维护性。
降低了类的复杂度,将一对多转化成了一对一。
缺点:

中介者对象通常具有较高的复杂性,难以实现。
当对象之间的交互较少或简单时,中介者模式可能会增加系统的一些不必要的复杂性。
随着系统的扩大,中介者模式的复杂度可能会增加,使得代码难以维护。
四、应用场景
4.1 生活场景
物流公司:通常作为中介者来协调包裹和货物的运输、仓储和投递等工作,同时保证货物的质量和安全,提高物流效率和服务水平。
某宝:管理各个商家和用户之间的交易信息,负责物流、支付等方面的处理,同时收取一定的手续费。
论坛和社交网络:处理用户之间的交流、分享和反馈等信息,同时处理违规信息和言论。
eg:只要是需要协调各方之间的合作和交互的领域,都有可能会涉及到中介者模式。

4.2 java场景

MVC架构:MVC架构中的控制器(Controller)部分,负责协调模型(Model)和视图(View)之间的交互。
SPring:Spring框架中的事件机制和发布/订阅模式,通过应用程序上下文(Application
Context)作为中介者,不同的组件可以通过事件监听器和发布者-订阅者模式进行交互。
消息队列:消息队列是一个典型的使用中介者模式的例子,消息队列系统中的中介者负责接收、存储和分发消息。

五、代码实现
下面以物流公司协调运输公司和商家为例,解释一下中介者模式。 在物流公司中,中介者是一个"物流中心",表示用于协调和管理各个参与方(运输公司、客户等)之间的交互关系。

5.0 UML类图
在这里插入图片描述

5.1 抽象中介者(Mediator)——LogisticsCenter

/**
 * 
 * 1.抽象中介者(Mediator):物流中心
 * 定义:用于协调各个同事对象之间交互的通用接口
 */
public interface LogisticsCenter {
    // 参与方注册方法,用于新增参与方
    void register(Participant participant);
 
    // 发送信息方法,用于同事之间的信息传递
    void send(String from, String to, String message);
}

5.2 抽象同事类(Colleague)——Participant

/**
 * 
 * 2.抽象同事类(Colleague):参与者(同事)
 * 定义:保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
 */
public abstract class Participant {
    // 中介者对象
    protected final LogisticsCenter logisticsCenter;
 
    public Participant(LogisticsCenter logisticsCenter) {
        this.logisticsCenter = logisticsCenter;
    }
 
    // 消息发送方法,根据传递给中介者
    public abstract void send(String to, String message);
 
    // 消息接收方法,由中介者调用
    public abstract void receive(String message);
}

5.3 具体同事类(Concrete Colleague)——TransportCompany&Merchant

/**
 * 
 * 3.具体同事类(Concrete Colleague):运输公司
 * 定义:实现抽象同事类接口,当需要与其他同事对象交互时,
 * 由中介者对象负责后续的交互,简单地说就是维护和中介者对象的通信。
 */
public class TransportCompany extends Participant{
 
    public TransportCompany(LogisticsCenter logisticsCenter) {
        super(logisticsCenter);
    }
 
    // 消息发送方法的实现,发送信息给中介者对象
    @Override
    public void send(String to, String message) {
        logisticsCenter.send("运输公司", to, message);
    }
 
    // 消息接收方法的实现,打印接收信息的内容
    @Override
    public void receive(String message) {
        System.out.println("运输公司接到消息: " + message);
    }
}
/**
 * 
 * 3.具体同事类(Concrete Colleague):商家
 * 定义:实现抽象同事类接口,当需要与其他同事对象交互时,
 * 由中介者对象负责后续的交互,简单地说就是维护和中介者对象的通信。
 */
public class Merchant extends Participant{
 
    public Merchant(LogisticsCenter logisticsCenter) {
        super(logisticsCenter);
    }
 
    // 消息发送方法的实现,发送信息给中介者对象
    @Override
    public void send(String to, String message) {
        logisticsCenter.send("商家", to, message);
    }
 
    // 消息接收方法的实现,打印接收信息的内容
    @Override
    public void receive(String message) {
        System.out.println("商家接收到消息: " + message);
    }
}

5.4 具体中介者(Concrete Mediator)——LogisticsCenterImpl

/**
 * 
 * 4.具体中介者(Concrete Mediator):物流公司
 * 定义:实现抽象中介者接口,定义一个List来管理同时对象,
 *      协调各个同事对象之间的交互,依赖于同事角色。
 */
public class LogisticsCenterImpl implements LogisticsCenter{
 
    // 参与方列表,用于管理同事之间的交互关系
    private final Map<String, Participant> participants = new HashMap<>();
 
    // 参与方注册方法的实现,向同事列表中添加参与方
    @Override
    public void register(Participant participant) {
        participants.put(participant.getClass().getSimpleName(), participant);
    }
 
    // 发送信息方法的实现,根据接收方信息调用接收方的消息接收方法
    @Override
    public void send(String from, String to, String message) {
        Participant participant = participants.get(to);
        if (participant != null) {
            participant.receive("Message from " + from + ": " + message);
        }
    }
}

5.5 testMediator

/**
 * 
 * 中介者模式测试类
 */
@SpringBootTest
public class TestMediator {
 
    @Test
    void testMediator(){
        //创建物流中心对象
        LogisticsCenter logisticsCenter = new LogisticsCenterImpl();
        //运输公司
        TransportCompany company = new TransportCompany(logisticsCenter);
        //商家
        Merchant merchant = new Merchant(logisticsCenter);
        //都注册到物流中心
        logisticsCenter.register(company);
        logisticsCenter.register(merchant);
        //发送消息给物流公司(中介者)
        company.send("Merchant", "快递已送达");
        merchant.send("TransportCompany", "收到,幸苦了");
    }
}

六、总结
当出现以下情况,可以考虑使用中介者模式:

如果对象之间的交互关系复杂且难以维护,或者对象之间需要大量的相互调用和信息传递,可以考虑使用中介者模式来简化对象之间的通信和协调。
如果对象之间紧密耦合,修改一个对象可能会影响到其他相关对象,使得系统难以进行扩展和维护。使用中介者模式可以降低对象之间的耦合度,使得对象可以独立变化和复用。
当系统中存在一个有组织结构的集合,并且该集合中的对象之间需要相互通信和协作时。比如,一个群聊系统中的参与者之间需要进行信息传递和交流,此时可以使用中介者模式来管理参与者之间的通信。
当需要集中化管理和控制一些公共行为或操作时。中介者模式可以充当一个中心协调者,负责管理和调度相关对象的行为或操作。例如,在一个电梯控制系统中,电梯调度器扮演中介者的角色,控制电梯的运行和调度。
总结一下,中介者模式可以有效地降低对象之间的耦合度,简化对象之间的交互。适用于对象之间的关系非常复杂,需要协调处理的情况,从而提高代码的可维护性和可扩展性。但是,如果应用不当,可能会使得系统的复杂度增加,不利于代码的维护和扩展。因此,在使用中介者模式时需要掌握适当的使用场景。

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

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

相关文章

creator-webview加载优化

title: creator-webview加载优化 categories: Cocos2dx tags: [cocos2dx, creator, webview, 优化, 加载, 性能] date: 2024-03-02 13:17:20 comments: false mathjax: true toc: true creator-webview加载优化 前篇 Android WebView shouldInterceptRequest - https://www.ji…

得物布局构建耗时优化方案实践

一、背景 当谈到移动应用程序的体验时&#xff0c;页面启动速度是其中至关重要的一点&#xff0c;更快的页面展示速度确保应用程序可以迅速加载并响应用户的操作, 从而提高用户使用 App 时的满意度。在页面启动的整个流程中&#xff0c;随着 UI 复杂度的上升&#xff0c;布局的…

jmeter发送请求参数如何使用变量

问题描述 发送jmeter请求时&#xff0c;想设置请求参数为变量 解决方法

190基于matlab的tfrSTFT时频分布图

基于matlab的tfrSTFT时频分布图&#xff0c;计算时间序列的STFT时频分布图&#xff0c;得到瞬时频率。通过GUI可以调节图像的展示样式。程序已调通&#xff0c;可直接运行。 190 STFT时频分布图 瞬时频率 能量谱 (xiaohongshu.com)

剪切板工具Ditto

https://github.com/sabrogden/Ditto/releases 1.开源免费Ditto 快捷键 ctrl (j键盘 esc下面的符号) 挺好用的&#xff0c;解决问题 投标中需要重复填写的内容&#xff0c;可以通过他进行 实时复制信息 2.windows自带的黏贴板工具 win键v调出快捷键

数字孪生+工业互联网标识解析,打造智能工厂新标杆!

当前&#xff0c;工业4.0浪潮愈发澎湃&#xff0c;加快数字化、网络化、智能化发展成为了制造业转型升级的必然要求。 51WORLD基于数字孪生技术与工业互联网标识解析体系&#xff0c;打造了一个集协同化供应、个性化定制、智能化生产于一体的全连接产线孪生平台&#xff08;以…

电脑记事本分类密码怎么设置?记事本备忘录分类密码设置方法

身为一名文字工作者&#xff0c;我每天都需要在电脑上记录大量的信息和灵感。电脑记事本备忘录对我来说&#xff0c;就像是一位随时待命的助手&#xff0c;帮助我捕捉每一个稍纵即逝的想法。然而&#xff0c;在开放的办公环境中&#xff0c;我总有些隐隐的担忧——毕竟&#xf…

【Python】新手入门学习:详细介绍组合/聚合复用原则(CARP)及其作用、代码示例

【Python】新手入门学习&#xff1a;详细介绍组合/聚合复用原则&#xff08;CARP&#xff09;及其作用、代码示例 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集…

Affinity Photo:像素大师,影像重塑者 mac/win版

在数字图像处理领域&#xff0c;Affinity Photo已经崭露头角&#xff0c;成为许多专业摄影师和图像设计师的首 选工具。这款软件不仅具备丰富的功能和强大的性能&#xff0c;还提供了直观易用的操作界面&#xff0c;让用户能够轻松实现高质量的图像处理。 Affinity Photo 软件…

通过el-select选择器和el-tree树形结构二次封装(vue2+elementUI),开发element-plus的TreeSelect树形选择器

需求&#xff1a; 领导看我在另一个vue3项目的el-tree-select挺好的&#xff0c;叫我移入vue2的项目中。 但是vue2版本的elementUI&#xff0c;并没有这个组件&#xff0c;所以只能自己找&#xff0c;找半天找不到和它差不多的&#xff0c;通过网友写的组件改写的 参考链接&…

vMware WorkStation创建虚拟机安装CentOS7,NAT模式配置网络

一、安装虚拟机 1、选择典型&#xff08;推荐&#xff09;配置 2、选择稍后安装操作系统 3、操作系统选择CentOS7 64位 4、虚拟机命名、选择安装位置 6、指定磁盘容量 7、指定磁盘容量 步骤&#xff1a; &#xff08;1&#xff09;、系统内存2GB &#xff08;2&#xff09;、…

c++中string的模拟实现(超详细!!!)

1.string的成员变量、&#xff08;拷贝&#xff09;构造、析构函数 1.1.成员变量 private:char* _str;size_t _size; //string中有效字符个数size_t _capacity; //string中能存储有效字符个数的大小 1.2&#xff08;拷贝&#xff09;构造函数 //构造函数string(const char* …

IDEA 2022.1以上版本 配置使用新UI

1、进入此页面的快捷建CtrlAltShift/ 2、新UI配置 3、原设置

算法练习:二分查找

目录 1. 朴素二分查找2. 在排序数组中查找元素的第一个和最后一个位置3. 搜索插入位置4. x的平方根5. 山脉数组的峰值索引6. 寻找峰值7. 寻找旋转排序数组中的最小值8. 点名 1. 朴素二分查找 题目信息&#xff1a; 题目链接&#xff1a; 二分查找二分查找的使用前提为数据具有&…

System类 --java学习笔记

System System代表程序所在的系统&#xff0c;也是一个工具类 常见System方法&#xff1a; 按照惯例&#xff0c;exit括号中非零状态码表示异常终止&#xff0c;填零则表示人为终止 currentTimeMillis&#xff08;&#xff09;返回的是long类型的时间毫秒值&#xff1a;指的…

iOS增量报告生成方案

一&#xff0c;iOS覆盖率报告生成逻辑 iOS覆盖率报告生成与Android有很大的不同&#xff0c;主要的生成逻辑如下&#xff1a; 1&#xff0c;将profraw文件&#xff0c;通过命令xcrun llvm-profdata merge -sparse转换成profdata; 2&#xff0c;再将profdata文件&#xff0c;通…

SCI 机器视觉领域期刊,审稿周期

(1)pattern recognition letters, 从投稿到发表&#xff0c;一年半时间 (2)Pattern recognition 不好中&#xff0c;时间长 (3)IEICE Transactions on Information and Systems&#xff0c; 作者中有一个必须是会员。收费高&#xff0c;审稿快。影响因子0.4 (4)Internationa…

SpringBoot实战项目——博客笔记项目

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、项目介绍二、项目的整体框架 2.1 数据库模块 2.2 前端模块 2.3 后端模块三、项目图片展示四、项目的实现 4.1 准备工作 4.…

PHP爬虫技术:利用simple_html_dom库分析汽车之家电动车参数

摘要/导言 本文旨在介绍如何利用PHP中的simple_html_dom库结合爬虫代理IP技术来高效采集和分析汽车之家网站的电动车参数。通过实际示例和详细说明&#xff0c;读者将了解如何实现数据分析和爬虫技术的结合应用&#xff0c;从而更好地理解和应用相关技术。 背景/引言 随着电…

git svn混用

背景 项目代码管理初始使用的svn, 由于svn代码操作&#xff0c;无法在本地暂存&#xff0c;有诸多不便&#xff0c;另外本人习惯使用git. 所以决定迁移至git管理 迁移要求&#xff1a; 保留历史提交记录 迁移流程 代码检出 git svn svn_project_url git代码提交 修改本…