Java设计模式之中介者模式详解

Java设计模式之中介者模式详解


一、中介者模式核心思想

核心目标通过中介对象封装一组对象间的交互,将网状的对象关系转变为星型结构。如同机场控制塔协调所有飞机的起降,避免飞机之间直接通信导致的混乱。


二、中介者模式类图(Mermaid)

协调
协调
通信
«interface»
Mediator
+notify(Component, String)
ConcreteMediator
-componentA: ComponentA
-componentB: ComponentB
+notify(Component, String)
«abstract»
Component
-mediator: Mediator
+setMediator(Mediator)
+notifyMediator(String)
ComponentA
+operationA()
+reactToB()
ComponentB
+operationB()
+reactToA()

三、代码实现示例

1. 聊天室场景

// 中介者接口
interface ChatMediator {void sendMessage(String msg, User user);void addUser(User user);
}// 具体中介者:聊天室
class ChatRoom implements ChatMediator {private List<User> users = new ArrayList<>();public void addUser(User user) {users.add(user);}public void sendMessage(String msg, User sender) {for (User user : users) {if (user != sender) {  // 不发送给自己user.receive(msg);}}}
}// 抽象组件
abstract class User {protected ChatMediator mediator;protected String name;public User(String name, ChatMediator mediator) {this.name = name;this.mediator = mediator;}public abstract void send(String msg);public abstract void receive(String msg);
}// 具体组件:聊天用户
class ChatUser extends User {public ChatUser(String name, ChatMediator mediator) {super(name, mediator);}public void send(String msg) {System.out.println(name + " 发送: " + msg);mediator.sendMessage(msg, this);}public void receive(String msg) {System.out.println(name + " 收到: " + msg);}
}// 客户端调用
public class Client {public static void main(String[] args) {ChatMediator chatRoom = new ChatRoom();User alice = new ChatUser("Alice", chatRoom);User bob = new ChatUser("Bob", chatRoom);User charlie = new ChatUser("Charlie", chatRoom);chatRoom.addUser(alice);chatRoom.addUser(bob);chatRoom.addUser(charlie);alice.send("大家好!");/* 输出:Alice 发送: 大家好!Bob 收到: 大家好!Charlie 收到: 大家好! */}
}

四、模式优缺点分析

✅ 优势

  • 解耦对象关系:组件间无需直接引用
  • 简化交互协议:统一通过中介者通信
  • 集中控制逻辑:交互规则在中介者中维护
  • 减少子类数量:避免为不同交互创建大量子类

❌ 缺点

  • 中介者可能复杂:随着交互增加,中介者可能成为"上帝对象"
  • 性能瓶颈:所有通信经过中介者,可能成为系统瓶颈
  • 过度设计风险:简单交互场景不适用

五、典型应用场景

  1. GUI组件交互:表单验证(输入框、按钮、标签联动)
  2. 聊天系统:群聊消息分发
  3. 航空管制:协调飞机起降
  4. 分布式系统:服务注册与发现(如Eureka)
  5. 工作流引擎:任务节点间的协调
  6. 游戏开发:NPC行为协调

六、Mermaid序列图(交互流程)

ComponentA Mediator ComponentB ComponentC 通知事件X 处理事件X 处理事件X 完成 完成 反馈结果 ComponentA Mediator ComponentB ComponentC

七、中介者模式 vs 其他模式

对比模式核心区别
观察者模式单向通知,不处理响应
外观模式简化子系统接口,不处理组件间交互
代理模式控制单个对象访问

八、实际框架应用案例

1. Java Message Service (JMS)

classDiagramclass ConnectionFactoryclass Connectionclass Sessionclass MessageProducerclass MessageConsumerConnectionFactory --> Connection : 创建Connection --> Session : 创建Session --> MessageProducer : 创建Session --> MessageConsumer : 创建MessageProducer --> Message : 发送MessageConsumer --> Message : 接收note for ConnectionFactory "作为中介者协调\n生产者与消费者"

2. Spring框架中的ApplicationContext

@Component
class ServiceA {@Autowired private ApplicationContext context;  // 中介者public void doSomething() {// 通过中介者获取其他组件ServiceB serviceB = context.getBean(ServiceB.class);serviceB.process();}
}

九、高级应用技巧

1. 中介者分层设计

协调
协调
GlobalMediator
ModuleAMediator
ModuleBMediator
ComponentA1
ComponentA2

2. 事件总线(简化版)

class EventBusMediator {private Map<Class<?>, List<Consumer<Object>>> handlers = new HashMap<>();public <T> void subscribe(Class<T> eventType, Consumer<T> handler) {handlers.computeIfAbsent(eventType, k -> new ArrayList<>()).add((Consumer<Object>) handler);}public void publish(Object event) {List<Consumer<Object>> eventHandlers = handlers.get(event.getClass());if (eventHandlers != null) {eventHandlers.forEach(handler -> handler.accept(event));}}
}// 使用示例
EventBusMediator bus = new EventBusMediator();
bus.subscribe(String.class, msg -> System.out.println("处理字符串: " + msg));
bus.publish("测试消息");

十、常见问题解答

Q1:如何避免中介者变成"上帝对象"?

  • 职责拆分:创建多个专业中介者(如登录中介者、支付中介者)
  • 使用状态模式:让中介者根据状态改变行为
  • 结合命令模式:将操作封装为命令对象

Q2:中介者模式如何支持异步?

class AsyncMediator {private Executor executor = Executors.newCachedThreadPool();public void mediate(Runnable task) {executor.execute(task);}
}

Q3:如何处理组件间的双向通信?

在中介者中实现回调机制:

interface Callback {void onComplete(Object result);
}class ComponentA {void request(Mediator mediator, Callback callback) {mediator.processRequest(this, callback);}
}class Mediator {void processRequest(ComponentA comp, Callback callback) {// 处理请求...callback.onComplete(result);}
}

如果你觉得文章对你有帮助的话,请帮忙点点关注吧!谢谢啦

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

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

相关文章

ArcGIS应用指南:基于网格与OD成本矩阵的交通可达性分析

随着城市化进程的加速,交通系统的效率和公平性日益成为影响居民生活质量的关键因素之一。在这一背景下,如何科学评估城市区域内的交通可达性,成为了城市规划、交通管理和公共政策制定中的重要议题。作为中国东南沿海的重要港口城市,厦门以其独特的地理优势和快速的城市发展…

基于NXP例程学习CAN UDS刷写流程

文章目录 前言1.概述1.1 诊断报文 2.协议数据单元(N_PDU)2.1 寻址信息&#xff08;N_AI&#xff09;2.1.1 物理寻址2.1.2 功能寻址2.1.3 常规寻址&#xff08;Normal addressing&#xff09;2.1.4 常规固定寻址&#xff08;Normal fixed addressing&#xff09;2.1.5 扩展寻址&…

近期手上的一个基于Function Grap(类AWS的Lambda)小项目的改造引发的思考

函数式Function是云计算里最近几年流行起来的新的架构和模式&#xff0c;因为它不依赖云主机&#xff0c;非常轻量&#xff0c;按需使用&#xff0c;甚至是免费使用&#xff0c;特别适合哪种数据同步&#xff0c;数据转发&#xff0c;本身不需要保存数据的业务场景&#xff0c;…

什么是 SQL 注入?如何防范?

什么是 SQL 注入?如何防范? 1. SQL 注入概述 1.1 基本定义 SQL 注入(SQL Injection)是一种通过将恶意SQL 语句插入到应用程序的输入参数中,从而欺骗服务器执行非预期SQL命令的攻击技术。攻击者可以利用此漏洞绕过认证、窃取数据甚至破坏数据库。 关键结论:SQL 注入是O…

高德地图应用OceanBase单元化构建下一代在线地图服务

IEEE International Conference on Data Engineering (ICDE) 是数据库和数据工程领域的顶级学术会议之一&#xff08;与SIGMOD、VLDB并成为数据库三大顶会&#xff09;&#xff0c;自1984年首次举办以来&#xff0c;每年举办一次。ICDE涵盖广泛的主题&#xff0c;包括数据库系统…

Vue3中Element-Plus中el-input及el-select 边框样式

如果不需要显示下边框&#xff0c;纯无边框直接将 【border-bottom: 1px solid #C0C4CC; 】注掉或去掉即可。 正常引用组件使用即可&#xff0c;无须自定义样式&#xff0c;最终效果CSS样式。 <style scoped> /* 输入框的样式 */ :deep(.el-input__wrapper) { box-sha…

如何做好一份技术文档:从信息孤岛到知识图谱的进阶之路

如何做好一份技术文档&#xff1a;从信息孤岛到知识图谱的进阶之路 在软件开发的漫长征程中&#xff0c;技术文档如同隐藏在代码丛林中的路标&#xff0c;不仅指引着开发团队的前行方向&#xff0c;更在产品迭代的岁月里构筑起知识传承的桥梁。一份优质的技术文档&#xff0c;既…

Docker Compose使用自定义用户名密码启动Redis

通常我们使用下面的命令来启动 redis 容器&#xff0c;此时连接 Redis 的时候是不需要用户认证的 sudo docker run -d --name my-redis -p 6379:6379 redis此时我们可以使用 redis-server --requirepass "mypassword" 来指定默认用户&#xff08;default&#xff09…

1.什么是node.js、npm、vue

一、Node.js 是什么&#xff1f; &#x1f63a; 定义&#xff1a; Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境&#xff0c;让你可以在浏览器之外运行 JavaScript 代码&#xff0c;主要用于服务端开发。 &#x1f63a;从计算机底层说&#xff1a;什么是“运…

如何在 Vue.js 中集成 Three.js —— 创建一个旋转的 3D 立方体

在这篇文章中&#xff0c;我将向大家展示如何将 Three.js 与 Vue.js 结合&#xff0c;创建一个简单的 3D 场景&#xff0c;并展示一个旋转的立方体。通过这个简单的示例&#xff0c;你将学习到如何在 Vue 项目中集成 Three.js&#xff0c;以及如何创建动态的 3D 内容。 1. 安装…

DeepSeek‑R1-0528 重磅升级:蚂蚁百宝箱免费、无限量调用

DeepSeek‑R1-0528 重磅升级&#xff1a;蚂蚁百宝箱免费、无限量调用 端午假期前一天&#xff0c;DeepSeek‑R1 更新到了 0528 版本&#xff01; 官方说明&#xff1a;0528 版本在深度思考与推理能力方面显著增强——在数学、编程与通用逻辑等多项基准测评中&#xff0c;表现已…

RS232转Profinet网关在检漏仪与西门子PLC里的应用

RS232转Profinet网关在检漏仪与西门子PLC里的应用 在工业自动化和控制领域&#xff0c;设备间的高效通信至关重要。RS232转Profinet网关作为一种关键的转换工具&#xff0c;能够将传统的RS232接口设备接入现代化的Profinet网络&#xff0c;从而实现数据的无缝传输和设备的远程…

jenkins-jenkins简介

一、简介 jenkins是一个可扩展的持续集成引擎。持续集成&#xff0c;也就是通常所说的CI&#xff08;Continues Integration&#xff09;&#xff0c;可以说是现代软件技术开发的基础。持续集成是一种软件开发实践&#xff0c; 即团队开发成员经常集成他们的工作&#xff0c;通…

vue发版html 生成打包到docker镜像进行发版

将Vue项目打包成Docker镜像部署主要分为以下几个步骤&#xff1a; 1. Vue项目打包‌ 执行npm run build生成dist文件夹&#xff0c;包含静态资源文件 注意检查index.html中资源引用路径是否正确&#xff08;避免绝对路径问题&#xff09; 2. 编写Dockerfile Copy Code FROM…

扫地机器人苦寻新引擎,大疆们却已攻入腹地

原创 科技新知 前沿科技组 作者丨江篱 编辑丨樱木、九黎 竞争激烈的扫地机器人赛道&#xff0c;迎来了新玩家。 据近日相关报道&#xff0c;大疆扫地机器人产品已开始量产&#xff0c;预计将于6月份发布。消息称大疆研发扫地机器人已超过四年&#xff0c;即将上市的产品是扫…

【C++】22. 红黑树封装实现Mymap和Myset

上一章节我们实现了红黑树&#xff0c;这一章节我们就用红黑树封装来实现一个我们自己的map和set 1. 源码及框架分析 SGI-STL 3.0版本的源代码中&#xff0c;map和set的实现主要分布在若干头文件中&#xff0c;这些头文件构成了这两个容器的完整实现架构&#xff1a; 核心头文…

02_redis分布式锁原理

文章目录 一、redis如何实现分布式锁1. 使用 SETNX 命令2. 设置过期时间3. 释放锁4. 注意事项5. 示例代码二、Java中分布式锁如何设置超时时间1. Redis分布式锁2. 基于Zookeeper的分布式锁3. 基于数据库的分布式锁注意事项一、redis如何实现分布式锁 Redis 实现分布式锁是一种…

酷派Cool20/20S/30/40手机安装Play商店-谷歌三件套-GMS方法

酷派Cool系列主打低端市场&#xff0c;系统无任何GMS程序&#xff0c;也不支持直接开启或者安装谷歌服务等功能&#xff0c;对于国内部分经常使用谷歌服务商店的小伙伴非常不友好。涉及机型有酷派Cool20/Cool20S /30/40/50/60等旗下多个设备。好在这些机型运行的系统都是安卓11…

技术为器,服务为本:AI时代的客服价值重构

在智能化浪潮中&#xff0c;大语言模型的出现为客户服务行业注入了全新动能。然而技术创新的价值不在于技术本身&#xff0c;而在于其赋能服务的深度与广度。AI对于我们来说&#xff0c;如同发动机之于汽车&#xff0c;重要的不是引擎参数&#xff0c;而是整车带给用户的驾驶体…

技术创新如何赋能音视频直播行业?

在全球音视频直播行业的快速发展中&#xff0c;技术的持续创新始终是推动行业进步的核心动力。作为大牛直播SDK的开发者&#xff0c;我很荣幸能分享我们公司如何从产品的维度出发&#xff0c;精准把握市场需求&#xff0c;并不断推动产品的发展&#xff0c;以满足不断变化的行业…