设计模式第18讲——中介者模式

news2024/12/23 5:40:12

目录

一、什么是中介者模式

二、角色组成

三、优缺点

四、应用场景

4.1 生活场景

4.2 java场景

五、代码实现

5.0 代码结构

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

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

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

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

5.5 testMediator

六、总结


一、什么是中介者模式

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

二、角色组成

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

三、优缺点

优点:

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

缺点:

  • 中介者对象通常具有较高的复杂性,难以实现。
  • 当对象之间的交互较少或简单时,中介者模式可能会增加系统的一些不必要的复杂性。
  • 随着系统的扩大,中介者模式的复杂度可能会增加,使得代码难以维护。

四、应用场景

4.1 生活场景

  • 物流公司:通常作为中介者来协调包裹和货物的运输、仓储和投递等工作,同时保证货物的质量和安全,提高物流效率和服务水平。
  • 某宝:管理各个商家和用户之间的交易信息,负责物流、支付等方面的处理,同时收取一定的手续费。
  • 论坛和社交网络:处理用户之间的交流、分享和反馈等信息,同时处理违规信息和言论。

eg:只要是需要协调各方之间的合作和交互的领域,都有可能会涉及到中介者模式。

4.2 java场景

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

五、代码实现

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

5.0 代码结构

 

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

/**
 * @author Created by njy on 2023/6/27
 * 1.抽象中介者(Mediator):物流中心
 * 定义:用于协调各个同事对象之间交互的通用接口
 */
public interface LogisticsCenter {
    // 参与方注册方法,用于新增参与方
    void register(Participant participant);

    // 发送信息方法,用于同事之间的信息传递
    void send(String from, String to, String message);
}

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

/**
 * @author Created by njy on 2023/6/27
 * 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

/**
 * @author Created by njy on 2023/6/27
 * 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);
    }
}
/**
 * @author Created by njy on 2023/6/27
 * 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

/**
 * @author Created by njy on 2023/6/27
 * 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

/**
 * @author Created by njy on 2023/6/28
 * 中介者模式测试类
 */
@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/699005.html

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

相关文章

Beego之Bee安装(Windows)以及创建,运行项目

一.简介 Bee是什么&#xff1f; bee工具是一个为了协助快速开发 Beego 项目而创建的项目&#xff0c;通过 bee 可以很容易的进行 Beego 项目的 创建、热编译、开发、测试和部署 Beego中文文档 Beego中文文档: Beego简介 安装前提 在安装bee之前&#xff0c;首先得提前安装好Go的…

【T3】打开财务报表提示不能登陆到服务器,请检查服务器配置。

【问题描述】 在使用畅捷通T3软件的时候&#xff0c; 打开【财务报表】提示&#xff1a;不能登陆到服务器&#xff08;GUPR7FM&#xff09;&#xff0c;请检查服务器配置。 但是打开【总账系统】&#xff0c;填制凭证、查看报表等操作都正常。 【解决方法】 由于操作【总账系…

【Java高级编程】Java反射机制

Java反射机制 1、反射的概述1.1、本章的主要内容1.2、关于反射的理解1.3、体会反射机制的“动态性”1.4、反射机制能提供的功能1.5、相关API 2、Class类的理解与获取Class的实例2.1、Class类的理解2.2、获取Class实例的几种方式2.3、总结&#xff1a;创建类的对象的方式2.4、Cl…

生产者与消费者问题

本篇文章我们使用C探讨一下生产者与消费者问题. 1. 多线程的引入 我们学习了操作系统, 知道了进程和线程的概念, 但是如果不进行代码实战的话, 会很难理解它们. 特别是编程的初学者(比如我), 在了解了进程和线程后通常会感到疑惑: 多线程怎么用? 为啥我平时写代码没有使用到…

ATM机项目实战——准备

项目介绍 大概功能&#xff1a; 实现一个模拟ATM机存款、取款、转账功能的一个系统&#xff0c;可以查看打印交易明细&#xff0c;后台用户可以管理用户账户卡信息。 适合人群&#xff1a; 在校计算机专业的大学生&#xff0c;愿意从事JAVA开发的人群&#xff0c;具体基础的…

记一次系统的jar包本地化方案

重在思路 行内容器环境,tomcat版本是8.5,导致jar包冲突,优先调用了jar包中的方法,致使同名同路径下,改写的类方法失效,报java.lang.NoSuchMethodError错误,删除对应class后需要重新更新jar包到行内maven私服仓库,流程复杂,且不清楚哪些地方依然有重写方法的地方,设置tomcat加载…

基于SSM+jsp的二手车交易网站设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

DBeaver mysql socks5 代理

DBeaver mysql socks5 代理 测试连接报错 Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.切换代理&#xff0c;连接成功 参考 DBeaver 文档 代理配置

谈一谈面试算法的几个常见误区

下一篇我们就开始梳理面试算法的体系了&#xff0c;今天呢&#xff0c;有个问题有必要谈一下——如何正确对待算法&#xff0c;如何征服算法。 目录 1.如何平常心对待算法 2.关于准备算法面试的一些误区 1.如何平常心对待算法 在老师之前算法班的群里&#xff0c;有位同学分…

vue3创建项目(五)vite配置端口号

Vue3配置代理跨域和服务端口等配置&#xff0c;可以在 vite.config.js 进行配置。(类似用 vue-cli 的 vue.config.js&#xff09; https://cn.vitejs.dev/config/第一步&#xff1a;首先在根目录下面创建vue.config.js import { defineConfig } from vite import vue from vite…

CubeMx打不开/不兼容大于java8的解决方案

最近在学习stm32&#xff0c;需要用到cubemx&#xff0c;但是软件都装好了却死活打不开 最后才发现是java版本的问题&#xff0c;cubemx只支持java8(至少java14,16,17,20亲测都不行) 于是便把java8又装了回来&#xff0c;但是又有新问题 不知道为什么&#xff0c;即便环境变量已…

Hologres弹性计算在OLAP分析上的实践和探索

作者&#xff1a;王奇 阿里云Hologres研发 简介&#xff1a; 1、本文介绍了OLAP分析在大数据分析中的位置 2、分析并介绍目前大数据OLAP遇到的分析性能、资源隔离、高可用、弹性扩缩容等核心问题 3、解析阿里云Hologres是如何解决极致性能、弹性、业务永续、性价比等核心刚需的…

从0到1 关于MySQL的数据库和表

一个字&#xff1a;细腻。 目录 1. 下载和安装MySQL及其可视化工具 2. 启动MySQL和客户端连接 3. 创建和查看数据库和表 1. 下载和安装MySQL及其可视化工具 下载和安装MySQL推荐博客&#xff1a; mysql数据库安装&#xff08;详细&#xff09;_体会&#xff01;的博客-CSD…

Idea部署 web项目时出现404问题

新手开发过程中发布项目可能会遇到这种问题&#xff0c;看到404&#xff0c;证明代码没有问题&#xff0c;地址有问题。 解决方法&#xff1a;&#xff08;此解决方法适用于&#xff0c;发布程序后首页能正常显示的情况下&#xff0c;点击任何菜单直接404&#xff09; 先看发布…

【NoSQL之 Redis配置与优化】

目录 一、关系数据库与非关系型数据库1、关系型数据库和非关系型数据库区别&#xff08;1&#xff09;数据存储方式不同&#xff08;2&#xff09;扩展方式不同&#xff08;3&#xff09;对事务性的支持不同 2、非关系型数据库产生背景总结 二、Redis简介1、Redis 具有以下几个…

数据库实验—触发器

为Students创建一触发器&#xff0c;并给出正反实例的SQL语句&#xff1a;当插入或修改一条学生记录时&#xff0c;确保此学生的入学年龄在14~40岁之间。 create trigger TRIGGER_Stu on Students for insert , update as declare age int select ageyear(getdate())-year(Sbir…

微信小程序——二维码推广海报

&#x1f60a;博主&#xff1a;爱学习的Akali King &#x1f60a;本文核心&#xff1a;本地图片和接口返回二维码制作一体化canvas海报 目录 创建一个画布通过canvas API绘制图像细节1 长按保存细节2 创建一个画布 在微信小程序中&#xff0c;我们使用<canvas>标签来创建…

微信小程序web-view嵌入uni-app H5页面,通过H5页面跳转其他小程序如何操作?

1、H5页面代码 wx.miniProgram.reLaunch({ url: /pages/index/index?appId${您的微信小程序appId} });//触发小程序刷新页面获取appId 微信小程序appId查看方法&#xff1a; 1&#xff09;有后台登录权限的情况下&#xff1a;登录微信公众平台后&#xff0c; 微信公众平台微信…

linux——在VMware Workstation中配置固定IP

第一步&#xff1a; 第二步&#xff1a; 第三步&#xff1a; 第四步&#xff1a; 切换到root用户下&#xff1a;用vim打开文件&#xff0c;进行上面五处修改。 改动后的文件为&#xff1a;

C++刷题第三天

203 移除链表元素 题目描述 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5] 解题思路…