二十一、中介者模式

news2024/11/28 21:37:24

一、什么是中介者模式

  中介者(Mediator)模式的定义:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。

  中介者模式包含以下主要角色:

  • 抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
  • 具体中介者(Concrete Mediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
  • 抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
  • 具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。

二、中介者模式的实现

  现在有多个同事类注册到中介者当中,要求其中一个同事发送消息,其他注册的同事都可以收到消息,代码实现如下:
1、抽象中介者

/**
 * @author FluffyCatkin
 * @version 1.0
 * @date 2020/1/7 0007 17:24
 * @description 抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法
 */
public interface  Mediator {
     void register(Colleague colleague);
     void relay(Colleague colleague);

}

2、抽象同事类


/**
 * @author FluffyCatkin
 * @version 1.0
 * @date 2020/1/7 0007 17:32
 * @description 抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
 */
public abstract class Colleague {
    protected Mediator mediator;

    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    public Colleague(Mediator mediator) {
        //注册对象到中介者 也可以不在这里注册,用户手动注册
        mediator.register(this);
        this.mediator = mediator;
    }

    public abstract void receive();
    public abstract void send();
}

3、具体中介者


/**
 * @author FluffyCatkin
 * @version 1.0
 * @date 2020/1/7 0007 17:27
 * @description 具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
 */
public class ConcreteMediator implements Mediator {
    private List<Colleague> colleagues = new ArrayList<>();

    @Override
    public void register(Colleague colleague) {
        if (!colleagues.contains(colleague)){
            colleagues.add(colleague);
        }
    }

    @Override
    public void relay(Colleague colleague) {
        colleagues.forEach(coll -> {
            if (!coll.equals(colleague)){
                coll.receive();
            }
        });
    }
}

4、具体同事类

  • 同事类1ConcreteColleague1

/**
 * @author FluffyCatkin
 * @version 1.0
 * @date 2020/1/7 0007 17:33
 * @description 具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
 */
public class ConcreteColleague1 extends Colleague {
    public ConcreteColleague1(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void receive() {
        System.out.println("ConcreteColleague1.................received......");
    }

    @Override
    public void send() {
        System.out.println("ConcreteColleague1.................send......");
        super.mediator.relay(this);
    }
}
  • 同事类2ConcreteColleague2

/**
 * @author FluffyCatkin
 * @version 1.0
 * @date 2020/1/7 0007 17:33
 * @description 具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
 */
public class ConcreteColleague2 extends Colleague {
    public ConcreteColleague2(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void receive() {
        System.out.println("ConcreteColleague2.................received......");
    }

    @Override
    public void send() {
        System.out.println("ConcreteColleague2.................send......");
        super.mediator.relay(this);
    }
}

5、测试类


/**
 * @author FluffyCatkin
 * @version 1.0
 * @date 2020/1/7 0007 16:54
 * @description 中介者模式
 *
 * 在现实生活中,常常会出现好多对象之间存在复杂的交互关系,这种交互关系常常是“网状结构”,它要求每个对象都必须知道它需要交互的对象。例如,每个人必须记住他(她)所有朋友的电话;而且,朋友中如果有人的电话修改了,他(她)必须告诉其他所有的朋友修改,这叫作“牵一发而动全身”,非常复杂。
 *
 * 如果把这种“网状结构”改为“星形结构”的话,将大大降低它们之间的“耦合性”,这时只要找一个“中介者”就可以了。如前面所说的“每个人必须记住所有朋友电话”的问题,只要在网上建立一个每个朋友都可以访问的“通信录”就解决了。这样的例子还有很多,例如,你刚刚参力口工作想租房,可以找“房屋中介”;或者,自己刚刚到一个陌生城市找工作,可以找“人才交流中心”帮忙。
 *
 * 在软件的开发过程中,这样的例子也很多,例如,在 MVC 框架中,控制器(C)就是模型(M)和视图(V)的中介者;还有大家常用的 QQ 聊天程序的“中介者”是 QQ 服务器。所有这些,都可以采用“中介者模式”来实现,它将大大降低对象之间的耦合性,提高系统的灵活性。
 * 模式的定义与特点:
 * 中介者(Mediator)模式的定义:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。
 *
 * 中介者模式是一种对象行为型模式,其主要优点如下:
 * 降低了对象之间的耦合性,使得对象易于独立地被复用。
 * 将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展。
 *
 * 其主要缺点是:当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护。
 * 模式的结构与实现:
 * 中介者模式实现的关键是找出“中介者”,下面对它的结构和实现进行分析。
 * 模式的结构:
 * 中介者模式包含以下主要角色。抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
 * 具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
 * 抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
 * 具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
 * 模式的应用场景:
 * 前面分析了中介者模式的结构与特点,下面分析其以下应用场景。当对象之间存在复杂的网状结构关系而导致依赖关系混乱且难以复用时。
 * 当想创建一个运行于多个类之间的对象,又不想生成新的子类时。
 */
public class Main {

    @Test
    public void mediatorTest(){
        Mediator mediator = new ConcreteMediator();
        Colleague colleague1 = new ConcreteColleague1(mediator);
        Colleague colleague2 = new ConcreteColleague2(mediator);
        //优化 可以把注册行为在创建对象的时候执行
//        mediator.register(colleague1);
//        mediator.register(colleague2);
        colleague1.send();
        System.out.println("---------------------------");
        colleague2.send();
    }
}

执行结果:


ConcreteColleague1.................send......
ConcreteColleague2.................received......
---------------------------
ConcreteColleague2.................send......
ConcreteColleague1.................received......


Process finished with exit code 0

三、应用场景

  中介者模式主要有以下应用场景:

  • 当对象之间存在复杂的网状结构关系而导致依赖关系混乱且难以复用时。
  • 当想创建一个运行于多个类之间的对象,又不想生成新的子类时。

四、优缺点分析

  中介者模式是一种对象行为型模式,其主要优点如下

  • 类之间各司其职,符合迪米特法则。
  • 降低了对象之间的耦合性,使得对象易于独立地被复用。
  • 将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展。

  其主要缺点是:中介者模式将原本多个对象直接的相互依赖变成了中介者和多个同事类的依赖关系。当同事类越多时,中介者就会越臃肿,变得复杂且难以维护。

代码地址:https://gitee.com/fluffycatkin/JavaDesignModel.git

image.png

原文出处:http://c.biancheng.net/view/1393.html

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

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

相关文章

Linux:ansible-playbook配置文件(剧本)

如果你还没有配置基础的ansible和一些基础用法可以去下面的链接 playbook是基于ansible的 Linux&#xff1a;ansible自动化运维工具_鲍海超-GNUBHCkalitarro的博客-CSDN博客 Linux&#xff1a;ansible自动化运维工具_鲍海超-GNUBHCkalitarro的博客-CSDN博客 Linux&…

4.5 放映演示文稿

制作完成的演示文稿最终是为了向观众进行展示&#xff0c;因此掌握演示文稿放映的技巧至关重要。本节主要介绍演示文稿放映的相关技巧&#xff0c;包括排练计时、自定义放映、设置放映方式以及墨迹画笔等内容。 4.5.1 排练计时 当进行演讲汇报时&#xff0c;常常要使用到幻灯…

【PHP】文件操作

文章目录 文件编程的必要性目录操作其它目录操作递归遍历目录PHP5常见文件操作函数PHP4常见文件操作函数其他文件操作函数 文件编程的必要性 文件编程指利用PHP代码针对文件&#xff08;文件夹&#xff09;进行增删改查操作。 在实际开发项目中&#xff0c;会有很多内容&…

kafka原理与应用

架构图 Broker Kafka集群包含多个服务器&#xff0c;服务器节点称为BrokerBroker存储Topic数据 如果某topic有N个partition&#xff0c;集群有N个broker&#xff0c;那么每个broker存储该topic的一个partition。如果某topic有N个partition&#xff0c;集群有(NM)个broker&#…

【期末复习笔记】计算机操作系统

计算机操作系统 进程的描述与控制程序执行进程进程的定义与特征相关概念定义特征进程与程序的区别 进程的基本状态和转换PCBPCB中的信息作用PCB的组织方式 线程进程与线程的比较 处理机调度与死锁处理机调度处理机调度的层次 调度算法处理机调度算法的目标处理机调度算法的共同…

C++ 多重继承

所谓多重继承就是一个儿子有好几个爹&#xff0c;然后一个人继承了这几个爹的财产。只需注意构造顺序即可&#xff0c;反正析构的顺序也是一样的。 #include <iostream> #include <string.h> using namespace std;class base_a { public:base_a(const char *str){…

内网隧道技术学习

1. 隧道技术 在进行渗透测试以及攻防演练的时候&#xff0c;通常会存在各种边界设备、软硬件防火墙、IPS等设备来检测外部连接情况&#xff0c;这些设备如果发现异常&#xff0c;就会对通信进行阻断。 那么隧道技术就是一种绕过端口屏蔽的通信方式&#xff0c;在实际情况中防…

自用Eclipse配置记录

喜欢用eclipse写代码&#xff0c;由于现在的eclipse配置导出的功能缺失较多。这里开一帖把本人常用的配置记录一番&#xff0c;省得再到处找。 另&#xff1a;工作空间中有个.metadata 目录保存了相关的插件及配置&#xff0c;可以复制到其他空工作间中复用配置。 设置工作空间…

【Tkinter系列07/15】小部件Message、下拉菜单、移动窗

17. 小部件Message 此小部件类似于小部件 &#xff08;请参见第 12 节 “标签小部件”&#xff09;&#xff0c;但它适用于 在多行上显示消息。所有文本将 以相同的字体显示;如果需要显示文本 使用多种字体&#xff0c;请参见第 24 节 “文本小部件”。Label 创建新构件作为子…

【AI】数学基础——数理统计(概念参数估计)

概率论 文章目录 3.6 数理统计概念与定理3.6.1 概率论与数理统计区别3.6.2 基本定理大数定理马尔科夫不等式切比雪夫不等式中心极限定理 3.6.3 统计推断的基本问题 3.7 参数估计3.7.1 频率派点估计法矩阵估计法极大似然估计点估计量的评估 区间估计 3.7.2 贝叶斯派贝叶斯定理条…

26、ADS瞬时波形仿真-TRANSIENT仿真(以共射放大器为例)

26、ADS瞬时波形仿真-TRANSIENT仿真&#xff08;以共射放大器为例&#xff09; 在本科期间&#xff0c;学习模电的时候总是要对各种三极管电路进行MULTISIM仿真&#xff0c;其实ADS具备相同的功能&#xff0c;而且对于射频电路&#xff0c;使用ADS进行仿真可以结合版图进行&am…

SpringBoot初级开发--整体应用的统一性异常管理(7)

在整个系统中&#xff0c;通常会要求有统一性的异常抛出&#xff0c;统一的异常格式&#xff0c;统一的异常界面&#xff0c;而不是把整个堆栈错误信息抛出&#xff0c;这样对整个系统的安全性以及错误定位都非常不好&#xff0c;接下来我们紧接上一章的源码&#xff0c;加上统…

23.手风琴效果

效果 源码 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>CSS Only Accordion Design</title><link rel="stylesheet" href="style.css"> </head> <bod…

ChatGPT辅助编写自动化测试

大家好&#xff0c;我是洋子&#xff0c;ChatGPT已经越来越火爆&#xff0c;国内百度、阿里等互联网大厂也纷纷投入大模型研究&#xff0c;OpenAI官网中提供了许多ChatGPT应用场景&#xff0c;例如SQL翻译、语言翻译、代码解释等 作为一名QA&#xff0c;我更关注ChatGPT生成的…

【全面讲解】CPU缓存一致性:从理论到实战(上)

本文从 CPU、缓存、内存屏障、CAS到原子操作&#xff0c;再到无锁实践&#xff0c;逐一详细介绍。 01存储体系结构 速度快的存储硬件成本高、容量小&#xff0c;速度慢的成本低、容量大。为了权衡成本和速度&#xff0c;计算机存储分了很多层次&#xff0c;扬长避短&#xff…

动态主机配置协议 (DHCP):简化网络中IP地址分配的利器

文章目录 一、引言二、什么是DHCP&#xff1f;三、DHCP的工作原理IP地址分配流程解决多服务器冲突IP地址租约更新 四、DHCP中继代理五、相关命令 首先可以看下思维导图&#xff0c;以便更好的理解接下来的内容。 一、引言 在局域网中&#xff0c;手动配置静态IP地址不仅繁琐…

22.3D等距社交媒体菜单的悬停特效

效果 源码 <!doctype html> <html><head><meta charset="utf-8"><title>CSS Isometric Social Media Menu</title><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.…

ThinkPHP 集成 jwt 技术 token 验证

ThinkPHP 集成 jwt 技术 token 验证 一、思路流程二、安装 firebase/php-jwt三、封装token类四、创建中间件&#xff0c;检验Token校验时效性五、配置路由中间件六、写几个测试方法&#xff0c;通过postman去验证 一、思路流程 客户端使用用户名和密码请求登录服务端收到请求&…

Android-关于页面卡顿的排查工具与监测方案

作者&#xff1a;一碗清汤面 前言 关于卡顿这件事已经是老生常谈了&#xff0c;卡顿对于用户来说是敏感的&#xff0c;容易被用户直接感受到的。那么究其原因&#xff0c;卡顿该如何定义&#xff0c;对于卡顿的发生该如何排查问题&#xff0c;当线上用户卡顿时&#xff0c;在线…

Android Aidl跨进程通讯(二)--异常捕获处理

学更好的别人&#xff0c; 做更好的自己。 ——《微卡智享》 本文长度为1623字&#xff0c;预计阅读5分钟 前言 上一篇《Android Aidl跨进程通讯的简单使用》中介绍了跨进程的通讯处理&#xff0c;在进程间的数据通过Aidl实现了交互&#xff0c;项目中经常会遇到Bug&#xff0c…