中介者模式(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. 模式结构
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. 最佳实践建议
- 合理划分职责:避免中介者承担过多责任
- 分层中介者:复杂系统可建立多级中介者
- 结合其他模式:
- 与观察者模式结合实现事件通知
- 与命令模式结合实现操作队列
- 使用接口编程:保持中介者和同事类的抽象性
- 异常处理机制:确保中介者可靠处理异常
- 性能优化:对高频交互进行批处理或异步处理
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);
🎯 设计原则体现:
- 迪米特法则:减少对象间的直接通信
- 单一职责原则:交互逻辑集中到中介者
- 开闭原则:新增同事类无需修改现有代码
通过中介者模式,可以有效地解耦复杂系统中的交互关系,特别适合需要集中管理多方交互的企业级应用场景。该模式在GUI开发、工作流引擎和分布式系统协调中应用广泛,是管理复杂对象关系的经典解决方案。