二十三种设计模式全面解析-解放组件间的通信束缚:深入探讨中介者模式的高级应用和进阶技巧


在软件开发中,组件之间的通信往往是不可避免的。然而,随着系统规模的增大和组件之间的相互依赖关系复杂化,直接的组件间通信往往会导致代码耦合度过高、可维护性下降等问题。为了解决这些问题,中介者模式应运而生。中介者模式通过引入一个中介者对象,将组件间的通信转变为间接的方式,从而降低了组件间的耦合度,提高了系统的灵活性和可维护性。


中介者模式在简化组件间通信、解耦依赖关系方面发挥着重要作用,但在实际应用中,我们还可以进一步提升其灵活性和可扩展性。本文将介绍中介者模式的高级应用和进阶技巧,包括事件驱动的中介者、中介者链和中介者的动态切换。


1. 事件驱动的中介者

传统的中介者模式中,组件之间的通信是通过中介者直接调用组件的方法来实现的。然而,在复杂的系统中,组件之间的通信可能涉及多个事件和动作,直接的方法调用方式显得不够灵活。事件驱动的中介者模式通过引入事件机制,使得组件之间的通信更加灵活和扩展。


在事件驱动的中介者模式中,组件之间不直接调用对方的方法,而是将事件发送给中介者,由中介者根据事件的类型和内容来触发相应的动作。这样,组件只需关注自身的事件处理逻辑,而无需了解其他组件的细节。
事件驱动的中介者模式可以提高系统的可扩展性和灵活性。当系统需要新增组件或修改组件间的通信逻辑时,只需通过定义新的事件和相应的处理逻辑,而无需修改已有的组件代码。

2. 中介者链

在某些情况下,系统中可能存在多个中介者,每个中介者负责不同领域或不同模块的组件间通信。此时,可以使用中介者链来实现多个中介者之间的协作。


中介者链是一种将多个中介者连接起来的方式,使得消息可以在中介者之间传递。当组件发送消息时,消息将依次传递给中介者链中的下一个中介者,直到到达目标组件。这样,不同领域或模块的组件可以通过中介者链进行通信,同时保持彼此的独立性。


中介者链可以提高系统的可扩展性和灵活性。当系统需要新增中介者或修改中介者之间的关系时,只需调整中介者链的配置,而无需修改已有的组件代码。


3. 中介者的动态切换

在某些情况下,系统需要根据不同的条件或场景切换中介者。例如,系统在不同的工作模式下可能需要使用不同的中介者来处理组件间的通信。


中介者的动态切换可以通过引入抽象工厂模式或配置文件来实现。通过抽象工厂模式,可以定义一个中介者工厂接口和多个具体的中介者工厂,根据条件或配置来动态创建不同的中介者。而通过配置文件,可以在运行时读取配置信息,选择合适的中介者实例进行使用。


中介者的动态切换可以提高系统的灵活性和可配置性。系统可以根据不同的需求动态选择合适的中介者,从而实现不同的通信策略和行为。

4、中介者链和中介者的动态切换案例

下面是一个更复杂的示例,展示了中介者链和中介者的动态切换的实现:


import java.util.ArrayList;
import java.util.List;// 定义事件接口
interface Event {void execute();
}// 定义组件接口
interface Component {void setMediator(Mediator mediator);void receiveEvent(Event event);void sendEvent(Event event);
}// 定义中介者接口
interface Mediator {void registerComponent(Component component);void sendEvent(Component sender, Event event);
}// 实现具体的事件
class ConcreteEvent implements Event {private String message;public ConcreteEvent(String message) {this.message = message;}public void execute() {System.out.println("Executing event: " + message);}}// 实现具体的组件
class ConcreteComponent implements Component {private Mediator mediator;private String name;public ConcreteComponent(String name) {this.name = name;}public void setMediator(Mediator mediator) {this.mediator = mediator;}public void receiveEvent(Event event) {System.out.println(name + " received event: " + event);// 处理事件逻辑}public void sendEvent(Event event) {System.out.println(name + " sending event: " + event);mediator.sendEvent(this, event);}}// 实现具体的中介者
class ConcreteMediator implements Mediator {private List<Component> components;private Mediator nextMediator;public ConcreteMediator() {components = new ArrayList<>();}public void setNextMediator(Mediator mediator) {this.nextMediator = mediator;}public void registerComponent(Component component) {components.add(component);}public void sendEvent(Component sender, Event event) {for (Component component : components) {if (component != sender) {component.receiveEvent(event);}}if (nextMediator != null) {nextMediator.sendEvent(sender, event);}}}public class Main {public static void main(String[] args) {Mediator mediator1 = new ConcreteMediator();Mediator mediator2 = new ConcreteMediator();Mediator mediator3 = new ConcreteMediator();Component component1 = new ConcreteComponent("Component 1");Component component2 = new ConcreteComponent("Component 2");Component component3 = new ConcreteComponent("Component 3");mediator1.registerComponent(component1);mediator2.registerComponent(component2);mediator3.registerComponent(component3);mediator1.setNextMediator(mediator2);mediator2.setNextMediator(mediator3);component1.setMediator(mediator1);component2.setMediator(mediator2);component3.setMediator(mediator3);Event event = new ConcreteEvent("Hello, world!");component1.sendEvent(event);}}

在这个示例中,我们定义了一个更复杂的中介者模式应用。我们有三个中介者对象 mediator1mediator2mediator3,以及三个组件对象 component1component2component3,每个组件都有一个唯一的名称。


我们通过 registerComponent 方法将组件注册到相应的中介者中,并通过 setNextMediator 方法设置中介者的下一个中介者。这样,我们就创建了一个中介者链。


sendEvent 方法中,中介者将事件依次传递给其他组件,并且如果有下一个中介者存在,则将事件传递给下一个中介者。


Main 类中,我们创建了中介者和组件对象,并将它们注册到中介者中。然后,我们设置中介者之间的关系,形成中介者链。最后,我们发送一个事件给第一个组件,事件将在中介者链中传递给其他组件。


总结:

中介者模式作为一种重要的设计模式,在实际应用中有许多高级应用和进阶技巧可以探索。本文介绍了事件驱动的中介者、中介者链和中介者的动态切换这三个方面的内容。希望这些信息能够为你提供一些启发,进一步应用和扩展中介者模式。

好了,今天的分享到此结束。如果觉得我的博文帮到了您,您的点赞和关注是对我最大的支持。如遇到什么问题,可评论区留言。


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

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

相关文章

解决 引element-plus依赖时的core-js报错

参考资料&#xff1a; https://blog.csdn.net/weixin_42164539/article/details/123388542 本人正在重构两年前搭建到一半的博客网站&#xff0c;相关依赖都很陈旧&#xff0c;用到了 npm-check-updates 检测项目可升级依赖&#xff1a; 补依赖过程始中报错 解决方案&#xf…

linux 内核同步互斥技术之信号量

信号量 信号量允许多个进程同时进入临界区&#xff0c;大多数情况下只允许一个进程进入临界区&#xff0c;把信号量的计数值设置为 1&#xff0c;即二值信号量&#xff0c;这种信号量称为互斥信号量。可允许多个锁持有者。 和自旋锁相比&#xff0c;信号量适合保护比较长的临界…

Java-宋红康-(P133-P134)-多线程创建方式(Thread and Runnable)

b站视频 133-多线程-线程创建方式1&#xff1a;继承Thread类_哔哩哔哩_bilibili 目录 3.1 继承Thread 3.1.1 继承Thread类方式 3.1.2 线程的执行流程 3.1.3 线程内存图 3.1.4 run()方法和start()方法 3.1.5 线程名字的设置和获取 3.1.6 获取运行main方法线程的名字 3.…

Linux进程间通信之共享内存

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;Linux &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 本博客主要内容讲解共享内存原理和相关接口的介绍&#xff0c;以及一个…

更换cmd下默认选择Python解释器

问题 我的电脑里有多个Python解释器&#xff0c;一个是自己下载的python37&#xff0c;版本是3.7.0&#xff0c;一个是anaconda的base环境&#xff0c;版本是3.7.4&#xff0c;还有虚拟环境里的python解释器。 最近发现&#xff0c;在cmd下输入python&#xff0c;使用的是anac…

肺是人体的第一道防线,流感频发季节,最有效的养肺方法你得知道!

肺脏是人体的第一道防线&#xff0c;牵动着整个呼吸道的健康&#xff0c;一旦肺脏受损&#xff0c;易引发咳嗽、气喘甚至肺炎。在流感、呼吸道疾病高发的冬季&#xff0c;如何呵护肺脏&#xff0c;保持身体健康&#xff1f; 全民养肺&#xff0c;刻不容缓 养肺不仅仅是中老年朋…

深入浅出之中央空调体系架构及楼宇自控系统

一、关于建筑节能 1、建筑能耗 在中国&#xff0c;建筑能耗占社会总能耗45.5%。来源&#xff1a;《中国建筑能耗研究报告&#xff08;2022&#xff09;》 2、空调、采暖、照明占比最高 建筑节能是指在保证、提高建筑舒适性和生活质量的条件下&#xff0c;在建筑物使用的全过…

12.5 作业

1&#xff0c; 以下是一个简单的比喻&#xff0c;将多态概念与生活中的实际情况相联系&#xff1a; 比喻&#xff1a;动物园的讲解员和动物表演 想象一下你去了一家动物园&#xff0c;看到了许多不同种类的动物&#xff0c;如狮子、大象、猴子等。现在&#xff0c;动物园里有…

RocketMQTemplate 发送消息的高级用法

Apache RocketMQ 是一款强大的分布式消息中间件&#xff0c;与 Spring Boot 集成后&#xff0c;通过 RocketMQTemplate 可以实现在应用程序中方便地发送消息。在本文中&#xff0c;我们将深入探讨 RocketMQTemplate 的一些高级用法&#xff0c;以提供更灵活的消息发送和控制。 …

7天快速学习计算机基础必考八股文day02:操作系统

day02操作系统目录一览图 请简述对进程的理解——操作系统的进程详解请简述同步与异步的区别——进程状态模型详解请简述进程和线程的区别——操作系统线程详解请简述什么是操作系统的内核态——用户态与内核态详解IO密集型任务部署需要注意什么——程序运行类型分析协程是什么…

找鞍点(PTA)

先找出每一行的max&#xff0c;然后在判断这个数是不是这一列的min #include <stdio.h> int main() { int i 0; int i1 0; int j1 0; int k 0; int j 0; int arr[6][6] { 0 }; int n 0; int i2 0; int max 0; int min…

【Qt开发流程】之对象模型2:属性系统

描述 Qt提供了一个复杂的属性系统&#xff0c;类似于一些编译器供应商提供的属性系统。然而&#xff0c;作为一个独立于编译器和平台的库&#xff0c;Qt不依赖于非标准的编译器特性&#xff0c;如__property或[property]。 Qt解决方案适用于Qt支持的所有平台上的任何标准c编译…

C++ vector建立无向图并遍历

如果题目中&#xff0c;以[[1,2],[1,3],[1,4],[2,3],....]这种方式给出边。可用使用vector建图。 首先定义一个二维的vector vector<vector<int>>g(n1);//n为顶点数 然后遍历每一条边&#xff0c;假设遍历时两边的顶点分别为a,b。如果是无向边&#xff0c;则可添加…

操作系统选择错题

编译器实质是程序指令,不由操作系统管理 **闲逛进程:**当系统中没有就绪进程时,闲逛进程idle一直运行,优先级最低,不需要除cpu以外的任何资源 多任务操作系统具有并发和并行的特点 操作系统通过硬件地址机制保护进程的地址空间,使得每个进程只能访问自己的地址空间。 不同…

力扣第374场周赛题解

这一场周赛的题目是比较难的一次&#xff0c;写了1个多小时就写了两个题目。 首先第一题&#xff1a; 纯水题&#xff0c;遍历然后进行一下判断就可以解决了。这边就不放代码了。 第二题&#xff1a; 这个题目&#xff0c;我觉得难度非常大&#xff0c;其实代码量也不大都是很…

IOday3作业

1> 使用文件IO完成对图像的读写操作 #include<myhead.h>int main(int argc, const char *argv[]) {//只读打开图片int fd-1;if((fd open("./R-C.bmp",O_RDWR))-1){perror("open");return -1;}//向后便宜两个字节找到大小的起始地址lseek(fd,2,S…

【数据结构】二叉树的实现

目录 1. 前言2. 二叉树的实现2.1 创建一棵树2.2 前序遍历2.2.1 分析2.2.2 代码实现2.2.3 递归展开图 2.3 中序遍历2.3.1 分析2.3.2 代码实现2.3.3 递归展开图 2.4 后序遍历2.4.1 分析2.4.2 代码实现2.4.3 递归展开图 2.5 求节点个数2.5.1 分析2.5.2 代码实现 2.6 求叶子节点个数…

Linux 调试器 --- g d b 使用

目录 一&#xff1a;gdb简介 二&#xff1a;示例代码 三&#xff1a;使用 1.启动gdb 2.各种指令 <1>: 查看源代码 <2>:设置断点 <3>:查看断点信息 <4>:删除断点 <5>: run <6>:逐过程调试 <7>:逐语句调试 <8>:查…

TrustZone​之在安全状态之间切换

如果处理器处于NS.EL1,而软件想要转移到S.EL1,应该如何实现呢? 要改变安全状态,无论是向上还是向下,执行都必须经过EL3,如下图所示: 前面的图表显示了在不同安全状态之间移动涉及的步骤的示例序列。逐步进行解释: 进入较高的异常级别需要一个异常。通常,此异常…

【JavaWeb】项目后端部分统一解决方案

项目后端部分统一解决方案 文章目录 项目后端部分统一解决方案一、异步响应规范格式类二、MD5加密工具类三、JwtHelper工具类四、CrosFilter过滤器 一、异步响应规范格式类 Result类 package com.pro.common;/*** 全局统一返回结果类**/ public class Result<T> {// 返…