深入浅出设计模式 - 中介者模式

news2024/11/15 23:39:26

博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌

Java知识图谱点击链接:体系化学习Java(Java面试专题)

💕💕 感兴趣的同学可以收藏关注下不然下次找不到哟💕💕

在这里插入图片描述

文章目录

  • 1、什么是中介者模式
  • 2、中介者模式的优缺点
  • 3、中介者模式的应用场景
  • 4、中介者模式的结构
  • 5、中介者模式的原理
  • 6、中介者模式的代码案例

1、什么是中介者模式

中介者模式是一种行为型设计模式,用于降低多个对象之间的耦合性。在中介者模式中,多个对象之间不直接相互通信,而是通过一个中介者对象进行通信。中介者对象封装了对象之间的交互逻辑,使得对象之间的通信变得简单而灵活。

中介者模式的核心思想是将对象之间的交互逻辑集中管理,避免了对象之间的直接依赖关系,从而提高了系统的可维护性和扩展性。通过引入中介者对象,可以将系统中复杂的交互关系变为多个简单的一对多关系,使得系统更易于理解和维护。

2、中介者模式的优缺点

中介者模式的优点包括:

  1. 降低了对象之间的耦合性:中介者模式将对象之间的交互逻辑集中在中介者对象中,使得对象之间不直接相互通信,从而降低了对象之间的耦合性。

  2. 简化了对象之间的交互:通过引入中介者对象,可以将复杂的交互关系变为多个简单的一对多关系,使得对象之间的通信变得简单而灵活。

  3. 提高了系统的可维护性和扩展性:由于对象之间的交互逻辑集中在中介者对象中,当系统需要修改交互逻辑时,只需修改中介者对象而不影响其他对象,提高了系统的可维护性和扩展性。

  4. 促进了代码复用:中介者模式将对象之间的通信逻辑集中在中介者对象中,使得这些逻辑可以被多个对象共享和复用。

中介者模式的缺点包括:

  1. 中介者对象可能会变得复杂:随着系统中对象之间的交互关系增多,中介者对象可能会变得复杂,包含大量的逻辑和方法。

  2. 中介者模式可能导致单点故障:由于多个对象之间的通信都依赖于中介者对象,如果中介者对象出现问题,可能会导致整个系统的功能受影响。

  3. 中介者模式可能降低系统的性能:由于中介者对象需要处理多个对象之间的通信,可能会导致系统的性能下降。

因此,在使用中介者模式时,需要权衡其优点和缺点,根据具体的场景来选择是否使用该模式。

3、中介者模式的应用场景

中介者模式适用于以下场景:

  1. 多个对象之间存在复杂的交互关系:当系统中多个对象之间存在复杂的交互关系,并且彼此之间的通信逻辑较为复杂时,可以使用中介者模式将这些交互逻辑集中在中介者对象中,简化对象之间的通信。

  2. 系统中对象之间的耦合性较高:当系统中的对象之间的耦合性较高,彼此之间的依赖关系较为复杂时,可以使用中介者模式将对象之间的交互逻辑解耦,通过引入中介者对象来降低对象之间的耦合性。

  3. 系统中的对象需要进行集中管理:当系统中的对象需要进行集中管理,例如需要对对象之间的通信进行调度、协调或控制时,可以使用中介者模式来管理这些对象。

  4. 系统中的对象之间的交互频繁且复杂:当系统中的对象之间的交互频繁且交互逻辑较为复杂时,可以使用中介者模式将这些复杂的交互逻辑集中在中介者对象中,提高系统的可维护性和扩展性。

  5. 系统中的对象之间存在循环依赖:当系统中的对象之间存在循环依赖关系,导致彼此之间难以直接通信时,可以使用中介者模式将这些循环依赖关系转化为一对多的关系,通过中介者对象来解决通信问题。

总之,中介者模式适用于对象之间存在复杂的交互关系、耦合性较高、需要集中管理、交互频繁且复杂、存在循环依赖等场景。通过引入中介者对象,可以简化对象之间的通信,提高系统的可维护性和扩展性。

4、中介者模式的结构

中介者模式的结构包括以下几个角色:

  1. 抽象中介者(Abstract Mediator):定义了中介者的接口,声明了各个同事对象之间通信的方法。

  2. 具体中介者(Concrete Mediator):实现了抽象中介者接口,协调各个具体同事对象之间的交互关系。

  3. 抽象同事类(Abstract Colleague):定义了同事类的接口,维护一个抽象中介者的引用,用于与其他同事对象进行通信。

  4. 具体同事类(Concrete Colleague):实现了抽象同事类的接口,具体同事对象之间通过中介者进行通信。

中介者模式的结构图如下:

|   Abstract Mediator |
+---------------------+
| + doSomething()     |
| + colleagueChanged()|
+---------------------+
                  /_\
                   |
                   |
          +------------------+
          |   Concrete      |
          |   Mediator      |
          +------------------+
          | + doSomething() |
          | + colleague1    |
          | + colleague2    |
          +------------------+
                   /_\
                    |
                    |
     +-------------------------+
     |   Abstract Colleague    |
     +-------------------------+
     | + mediator              |
     | + send(message)         |
     | + receive(message)      |
     +-------------------------+
                   /_\
                    |
                    |
     +-------------------------+
     |   Concrete Colleague 1  |
     +-------------------------+
     | + send(message)         |
     | + receive(message)      |
     +-------------------------+
                   /_\
                    |
                    |
     +-------------------------+
     |   Concrete Colleague 2  |
     +-------------------------+
     | + send(message)         |
     | + receive(message)      |
     +-------------------------+

在中介者模式中,抽象中介者定义了中介者的接口,具体中介者实现了该接口,并负责协调各个具体同事对象之间的交互关系。抽象同事类定义了同事类的接口,具体同事类实现了该接口,并通过中介者进行通信。通过中介者对象,各个同事对象之间的交互被集中在中介者对象中,从而降低了对象之间的耦合性。

5、中介者模式的原理

中介者模式的原理是通过引入一个中介者对象,将多个对象之间的交互行为集中管理和调度。在中介者模式中,各个对象之间不直接相互通信,而是通过中介者来进行通信和协调。

当各个对象之间需要进行复杂的通信和交互时,如果直接让它们相互引用,会导致对象之间的耦合度很高,难以维护和扩展。而中介者模式通过引入中介者对象,将对象之间的交互行为解耦,使得对象之间的通信通过中介者进行,从而简化了对象之间的关系。

中介者模式的核心思想是将对象之间的通信集中管理,通过中介者对象来协调各个对象之间的交互。当一个对象需要与其他对象进行通信时,它不需要直接与其他对象交互,而是通过中介者来发送和接收消息。中介者负责将消息传递给目标对象,并处理各个对象之间的交互逻辑。

通过中介者模式,可以实现一对多的关系,即一个中介者对象可以管理多个对象之间的交互。当一个对象发生变化时,只需要通知中介者对象,中介者对象会负责将变化传递给其他相关的对象。这样,对象之间的关系变得灵活可扩展,各个对象之间的耦合度也降低了。

总结来说,中介者模式通过引入中介者对象,将对象之间的通信和交互行为集中管理,解耦了对象之间的关系,提高了系统的灵活性和可扩展性。

6、中介者模式的代码案例

以下是一个简单的中介者模式的代码案例:

package com.pany.camp.design.principle.mediator;

/**
 *
 * @description:  接口类
 * @copyright: @Copyright (c) 2022
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0
 * @createTime: 2023-06-28 15:59
 */
public interface Mediator {

    void sendMessage(String message, Colleague colleague);
}


package com.pany.camp.design.principle.mediator;

/**
 *
 * @description: 具体中介者类
 * @copyright: @Copyright (c) 2022
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0
 * @createTime: 2023-06-28 16:00
 */
class ConcreteMediator implements Mediator {

    private Colleague colleague1;
    private Colleague colleague2;

    public void setColleague1(Colleague colleague1) {
        this.colleague1 = colleague1;
    }

    public void setColleague2(Colleague colleague2) {
        this.colleague2 = colleague2;
    }

    @Override
    public void sendMessage(String message, Colleague colleague) {
        if (colleague == colleague1) {
            colleague2.receiveMessage(message);
        } else if (colleague == colleague2) {
            colleague1.receiveMessage(message);
        }
    }
}

package com.pany.camp.design.principle.mediator;

/**
 *
 * @description:  抽象同事类
 * @copyright: @Copyright (c) 2022
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0
 * @createTime: 2023-06-28 16:00
 */
public abstract class Colleague {

    protected Mediator mediator;

    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }

    public abstract void sendMessage(String message);

    public abstract void receiveMessage(String message);
}

package com.pany.camp.design.principle.mediator;

/**
 *
 * @description: 具体同事类
 * @copyright: @Copyright (c) 2022
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0
 * @createTime: 2023-06-28 16:01
 */
public class ConcreteColleague1 extends Colleague {

    public ConcreteColleague1(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void sendMessage(String message) {
        mediator.sendMessage(message, this);
    }

    @Override
    public void receiveMessage(String message) {
        System.out.println("ConcreteColleague1 received message: " + message);
    }
}


package com.pany.camp.design.principle.mediator;

/**
 * @description: 具体同事类
 * @copyright: @Copyright (c) 2022
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0
 * @createTime: 2023-06-28 16:01
 */
public class ConcreteColleague2 extends Colleague {

    public ConcreteColleague2(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void sendMessage(String message) {
        mediator.sendMessage(message, this);
    }

    @Override
    public void receiveMessage(String message) {
        System.out.println("ConcreteColleague2 received message: " + message);
    }
}

package com.pany.camp.design.principle.mediator;

/**
 *
 * @description:  客户端
 * @copyright: @Copyright (c) 2022
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0
 * @createTime: 2023-06-28 16:01
 */
public class Client {

    public static void main(String[] args) {
        ConcreteMediator mediator = new ConcreteMediator();

        ConcreteColleague1 colleague1 = new ConcreteColleague1(mediator);
        ConcreteColleague2 colleague2 = new ConcreteColleague2(mediator);

        mediator.setColleague1(colleague1);
        mediator.setColleague2(colleague2);

        colleague1.sendMessage("Hello from colleague1");
        colleague2.sendMessage("Hi from colleague2");
    }
}

我们定义了一个中介者接口Mediator和具体中介者类ConcreteMediator。抽象同事类Colleague定义了同事类的基本行为,具体同事类ConcreteColleague1和ConcreteColleague2继承自Colleague并实现了具体的行为。在测试代码中,我们创建了中介者对象和两个具体同事对象,并将它们注册到中介者中。然后,通过调用同事对象的sendMessage方法发送消息,中介者会根据发送消息的同事对象将消息传递给其他同事对象。最后,每个具体同事对象接收到消息后会进行相应的处理。

这个简单的示例展示了中介者模式的基本原理和用法。实际应用中,中介者模式可以用于更复杂的对象之间的通信和协调。

输出结果如下:

ConcreteColleague2 received message: Hello from colleague1
ConcreteColleague1 received message: Hi from colleague2

Process finished with exit code 0

在这里插入图片描述

💕💕 本文由激流原创,首发于CSDN博客,博客主页 https://blog.csdn.net/qq_37967783?spm=1010.2135.3001.5421
💕💕喜欢的话记得点赞收藏啊
在这里插入图片描述

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

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

相关文章

C++之lambda表达式回调函数作为参数(一百四十)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

【python】matplotlib 绘制火山图、条形图

文章目录 火山图条形图 火山图 绘制火山图,输入是两个datafreme,行是样本名,列是基因名。使用T-test检验绘制基因表达情况。 def minmax_scale(data):import numpy as np# # 示例数据# data np.array([2, 4, 6, 8, 10])# 进行Min-Max标准化…

go并发编程之channel

目录 1.简介 2.channel类型 无缓冲区的channel 无缓冲区channel的创建 带缓冲区的channel 带缓冲区channel的创建 3.channel使用代码演示 4.获取channel中的值 ​编辑 5.单向channel 单向发送data,发送到channel中 单向接收,channel接收数据 6…

汇编的各种指令及使用方法

***************************************************************** 汇编中的符号 1.指令: 能够编译生成一条32位的机器码,且能被CPU识别和执行 2.伪指令:本身不是指令,编译器可以将其替换成若干条等效指令 3.伪操作&#xff1a…

Linux进程间通信——管道(下)

前文 一,什么是命名管道? 二,命名管道的基本原理 三,创建命名管道实现两个进程对写 四,匿名管道和命名管道的区别 总结 前文 上篇文章我们主要讲了匿名管道的定义以及基本原理,但是匿名管道有一个致命的缺陷&#…

HashSet、LinkedHashSet、TreeSet有什么区别

- HashSet、LinkedHashSet 和 TreeSet 都是 Set接口的实现类,都能保证元素唯一,并且都不是线程安全的。HashSet 的底层数据结构是哈希表(基于 HashMap 实现),元素存入和取出顺序不一致。LinkedHashSet 的底层数据结构…

C++制作五子棋

正文 01 思路 我没有选择专业的五子棋棋型,用我自己的逻辑(初高中玩五子棋的方法),去实现简单的人机对战。 首先因为要计算五子棋每一步的分数,那么你就要分析每一步形成的棋盘,以下图为例:…

蓝桥杯专题-试题版含答案-【风险度量】【括号配对问题】【ASCII码排序】【素数求和】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 👉关于作者 专注于Android/Unity和各种游…

【Java高级编程】枚举类注解

枚举类&注解 1、枚举类的使用1.1、枚举类的使用1.2、如何定义枚举类1.3、Enum类的主要方法 2、注解的使用2.1、注解的概述2.2、常见的Annotation示例2.3、如何自定义注解:参照SuppressWarnings定义2.4、JDK提供的4种元注解2.5、JDK 8中注解的新特性:…

2023-06-25:redis中什么是缓存穿透?该如何解决?

2023-06-25:redis中什么是缓存穿透?该如何解决? 答案2023-06-25: 缓存穿透 缓存穿透指的是查询一个根本不存在的数据,在这种情况下,无论是缓存层还是存储层都无法命中。因此,每次请求都需要访…

关于C++图论树的某些题图形提示

一、去教室的路。 猫猫大学有n条路,每条路都有一个数字编号,其中的一条路一定与另外2条路相连,请你打出这个学校的地图。 输入1: 1 2 3 4 2 3 45 4 45 1 输出1: 1 2 3 4 5 45 图解 &#xff1…

动态住宅代理VS静态住宅代理,怎么选择?

现在,越来越多的海外代理服务商均支持动态住宅IP与静态住宅IP,很多小伙伴就疑惑,这二者有什么区别呢?哪个更好?其实,没有哪个更好,只有哪一个更合适您的业务。 无论动态住宅IP还是静态住宅IP都来自真实的住…

【软件测试】10道性能测试高频面试题,你能答上多少?

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、性能测试包含了…

表格el-table多出一条横线,怎么解决(el-table表格下方多一条线的问题)

最近在写el-table表格的时候,发现的问题,表格多出一条横线, 可以看出其它行,都是正常显示,只有第7行多出一条横线,找了好久, 最后发现是el-table表格的伪元素,问题就出在这&#xf…

B站化播放量为播放时长,是谁的狂欢?

6月26日晚,B站举办了14周年庆典晚会。在晚会上,除了周深、美依礼芽同框献唱受到关注,B站董事长兼CEO陈睿的演讲内容同样值得深思: 一来,陈睿提到,要将目前B站视频前台显示的播放量数据从次数改为分钟数&am…

精进ARM计算架构,催生人工智能产业的巨大跨越

在优化ARM计算架构以支持人工智能应用方面,以下是一些常见的方法和技术: 算法和模型设计优化:选择合适的算法和模型结构对于在ARM架构上高效执行人工智能任务至关重要。设计轻量级的模型、减少冗余操作和参数量,使用适合ARM架构的…

【K8S系列】深入解析K8S调度

序言 做一件事并不难,难的是在于坚持。坚持一下也不难,难的是坚持到底。 文章标记颜色说明: 黄色:重要标题红色:用来标记结论绿色:用来标记论点蓝色:用来标记论点 Kubernetes (k8s) 是一个容器编…

扩展ExtendedFloatingActionButton滚动收缩展开行为

效果 首先ExtendedFloatingActionButton有默认的Behavior : ExtendedFloatingActionButtonBehavior,这个类是为了ExtendedFloatingActionButton不被SnakBar所遮挡,并且这个类它是protected,所以为了保留原有的设计,自定义的Behavior不能在外部定义&#…

Go语言单元测试

1、Go语言单元测试 Go语言中的测试依赖 go test 命令,go test 命令是一个按照一定约定和组织的测试代码的驱动程序。在包目录 内,所有以 _test.go 为后缀名的源代码文件都是 go test 测试的一部分,不会被 go build 编译到最终的可执行 文件…

【Python爬虫】利用爬虫抓取双色球开奖号码,获取完整数据,简洁45行代码实现,更新时间2023-06-28

链接:https://pan.baidu.com/s/18oE308_NVNPaCOACw_H5Hw?pwdabc1 利用爬虫抓取双色球开奖号码,获取完整数据,简洁45行代码实现,更新时间2023-06-28 这是网上的数据,怎么将它爬取下来 它将只爬取最近30期的双色球开…