java23种设计模式-中介者模式

embedded/2025/2/27 10:01:49/

中介者模式(Mediator Pattern)学习笔记


编程相关书籍分享:https://blog.csdn.net/weixin_47763579/article/details/145855793
DeepSeek使用技巧pdf资料分享:https://blog.csdn.net/weixin_47763579/article/details/145884039


1. 模式定义

行为型设计模式,通过定义一个中介对象来封装一系列对象之间的交互。减少对象间的直接耦合,使其可以独立改变交互方式。

2. 适用场景

✅ 对象之间存在复杂的网状引用关系
✅ 需要集中控制多个对象间的交互
✅ 需要限制对象之间的直接通信
✅ 希望复用组件间的交互逻辑
✅ 需要动态改变对象间的交互规则

3. 模式结构

knows
interacts-with
«interface»
Mediator
+notify(sender: Colleague, event: String)
ConcreteMediator
-colleagueA: Colleague
-colleagueB: Colleague
+notify()
«abstract»
Colleague
-mediator: Mediator
+setMediator()
+send()
+receive()
ConcreteColleagueA
+send()
+receive()
ConcreteColleagueB
+send()
+receive()

4. 核心角色

角色说明
Mediator抽象中介者,定义通信接口
ConcreteMediator具体中介者,协调各同事对象的行为
Colleague抽象同事类,持有中介者引用
ConcreteColleague具体同事类,通过中介者与其他同事通信

5. 代码示例

5.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 sendMessage(String msg, User user) {for (User u : users) {if (u != user) {  // 不发送给自己u.receive(msg);}}}public void addUser(User user) {users.add(user);}
}// 抽象同事类
abstract class User {protected ChatMediator mediator;protected String name;public User(ChatMediator med, String name) {this.mediator = med;this.name = name;}public abstract void send(String msg);public abstract void receive(String msg);
}// 具体同事类
class ChatUser extends User {public ChatUser(ChatMediator med, String name) {super(med, name);}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(chatRoom, "Alice");User bob = new ChatUser(chatRoom, "Bob");User charlie = new ChatUser(chatRoom, "Charlie");chatRoom.addUser(alice);chatRoom.addUser(bob);chatRoom.addUser(charlie);alice.send("大家好!");/* 输出:Alice 发送消息: 大家好!Bob 收到消息: 大家好!Charlie 收到消息: 大家好! */}
}

6. 模式变种

6.1 事件总线模式

// 基于观察者模式的扩展
class EventBusMediator {private Map<Class<?>, List<Consumer<?>>> handlers = new ConcurrentHashMap<>();public <T> void subscribe(Class<T> eventType, Consumer<T> handler) {handlers.computeIfAbsent(eventType, k -> new ArrayList<>()).add(handler);}public <T> void publish(T event) {List<Consumer<?>> consumers = handlers.get(event.getClass());if (consumers != null) {consumers.forEach(c -> ((Consumer<T>)c).accept(event));}}
}// 使用示例
EventBusMediator bus = new EventBusMediator();
bus.subscribe(String.class, msg -> System.out.println("处理字符串: " + msg));
bus.publish("测试消息");

7. 优缺点分析

✔️ 优点

  • 减少对象间耦合
  • 集中控制交互逻辑
  • 简化同事类实现
  • 符合迪米特法则
  • 便于扩展新的同事类

缺点

  • 中介者可能变得过于复杂(上帝对象)
  • 中介者故障会导致系统整体失效
  • 可能降低系统运行效率
  • 增加系统设计复杂度

8. 相关模式对比

模式目的关键区别
观察者模式对象间通知机制观察者模式是分布式,中介者是集中式
门面模式简化子系统接口门面模式侧重简化接口,中介者协调交互
代理模式控制对象访问中介者协调多个对象,代理控制单个对象

9. 实际应用案例

  • Java Timer的调度机制(协调多个TimerTask)
  • MVC框架的控制器(协调Model和View)
  • 航空管制系统(协调飞机通信)
  • GUI框架中的对话框组件交互
  • 游戏引擎中的碰撞检测系统
  • Spring框架的ApplicationContext
  • JMS(Java Message Service)的消息路由

10. 最佳实践建议

  1. 合理划分职责:避免中介者承担过多责任
  2. 分层中介者:复杂系统可建立多级中介者
  3. 结合其他模式
    • 与观察者模式结合实现事件通知
    • 与命令模式结合实现操作队列
  4. 使用接口编程:保持中介者和同事类的抽象性
  5. 异常处理机制:确保中介者可靠处理异常
  6. 性能优化:对高频交互进行批处理或异步处理

11. 扩展应用(订单处理系统)

// 中介者接口
interface OrderMediator {void placeOrder(Order order);void cancelOrder(String orderId);void notifyWarehouse(Order order);void notifyPayment(Order order);
}// 具体中介者
class OrderProcessor implements OrderMediator {private PaymentService payment;private WarehouseService warehouse;private NotificationService notification;public void placeOrder(Order order) {if (payment.process(order)) {warehouse.prepare(order);notification.sendEmail(order.getUser(), "订单已确认");}}// 实现其他方法...
}// 同事类示例
class PaymentService {private OrderMediator mediator;public boolean process(Order order) {// 支付处理逻辑...mediator.notifyWarehouse(order);return true;}
}// 客户端调用
OrderMediator mediator = new OrderProcessor();
Order order = new Order("123", 99.99);
mediator.placeOrder(order);

🎯 设计原则体现

  1. 迪米特法则:减少对象间的直接通信
  2. 单一职责原则:交互逻辑集中到中介者
  3. 开闭原则:新增同事类无需修改现有代码

通过中介者模式,可以有效地解耦复杂系统中的交互关系,特别适合需要集中管理多方交互的企业级应用场景。该模式在GUI开发、工作流引擎和分布式系统协调中应用广泛,是管理复杂对象关系的经典解决方案。


http://www.ppmy.cn/embedded/167502.html

相关文章

快速理解Raft分布式共识算法

目录 拜占庭将军问题 Raft算法是干什么的&#xff1f; 一、领导选举&#xff08;选老板&#xff09; 二、日志复制&#xff08;发通知&#xff09; 三、安全性&#xff08;防篡改&#xff09; &#x1f330; 举个真实例子 ✔️ Raft的优势 基础 状态机 节点类型 任期…

Imagination 最新的D系列GPU IP 为智能手机和其他电力受限设备上图形和计算工作负载的高效加速设定了新的标准

今日&#xff0c;Imagination Technologies&#xff08;“Imagination”&#xff09;宣布推出其最新的GPU IP——Imagination DXTP&#xff0c;该产品为智能手机和其他电力受限设备上图形和计算工作负载的高效加速设定了新的标准。得益于一系列微架构改进&#xff0c;DXTP在常见…

人工智能丨大语言模型不再高不可攀!DeepSeek开源FlashMLA,开启AI新纪元

在人工智能技术飞速发展的今天&#xff0c;DeepSeek宣布开源其核心大语言模型框架——FlashMLA&#xff0c;这一举动引发了业界的广泛关注。那么&#xff0c;DeepSeek开源FlashMLA&#xff0c;究竟意味着什么&#xff1f;这不仅是一次技术上的开放&#xff0c;更是对行业生态、…

mysql有索引但是查询没有使用索引是什么问题

关键原因分析 索引选择性问题 如果 order_id 没有索引&#xff0c;即使 insert_time 有索引&#xff0c;优化器可能认为先通过 order_id 过滤数据更高效。但由于 order_id 无索引&#xff0c;只能全表扫描后过滤。即使 insert_time 有索引&#xff0c;如果满足 insert_time >…

530 Login fail. A secure connection is requiered(such as ssl)-java发送QQ邮箱(简单配置)

由于cs的csdN许多文章关于这方面的都是vip文章&#xff0c;而本文是免费的&#xff0c;希望广大网友觉得有帮助的可以多点赞和关注&#xff01; QQ邮箱授权码到这里去开启 授权码是16位的字母&#xff0c;填入下面的mail.setting里面的pass里面 # 邮件服务器的SMTP地址 host…

MSSQL2022的一个错误:未在本地计算机上注册“Microsoft.ACE.OLEDB.16.0”提供程序

MSSQL2022导入Excel的一个错误&#xff1a;未在本地计算机上注册“Microsoft.ACE.OLEDB.16.0”提供程序 一、导入情况二、问题发现三、问题解决 最近在安装新版SQLServer SSMS 2022后&#xff0c;每次导入Excel都会出现错误提示&#xff1a;未在本地计算机上注册“Microsoft.…

DeepSeek开源周 Day02:从DeepEP开源趋势重新审视大模型Infra

DeepEP 今天DeepSeek开源周第二天&#xff0c;开放了DeepEP仓库&#xff0c;属实看了下源码&#xff0c;和昨天FlashMLA一样&#xff0c;C权重&#xff08;包括CUDA&#xff09;还是占据了绝对部分&#xff0c;作为调包侠的我&#xff0c;看到之后望而却步&#xff0c;想看原理…

Spring MVC框架六:Ajax技术

精心整理了最新的面试资料&#xff0c;有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 简介 jQuery.ajax Ajax原理 结语 创作不易&#xff0c;希望能对大家给予帮助 想要获取更多资源? 点击链接获取