中介者模式:解耦复杂系统的星型通信方案
1. 中介者模式:模块间解耦的终极方案
第一次接手大型电商系统重构时,我被订单、库存、支付、物流等模块间蜘蛛网般的调用关系震惊了。某个深夜,因为修改了优惠券模块的接口,导致积分系统异常崩溃——这正是典型的多模块直接耦合带来的灾难。中介者模式就像在混乱的战场上派出一位指挥官,让所有模块只需与中介者对话,彻底解决"牵一发而动全身"的问题。
2. 模式原理深度解析
2.1 核心角色拆解
- Mediator(抽象中介者):定义同事对象到中介者的接口
- ConcreteMediator(具体中介者):实现协调各同事对象的逻辑
- Colleague(同事类):所有需要交互的模块父类,持有中介者引用
典型实现中,各模块不再相互持有引用,而是通过中介者的notify方法传递事件。比如订单创建时,只需调用mediator.notify("ORDER_CREATED", orderData),中介者会自动触发库存扣减、支付初始化等后续流程。
2.2 通信机制对比
| 通信方式 | 直接调用 | 中介者模式 |
|---|---|---|
| 耦合度 | 高(网状结构) | 低(星型结构) |
| 可维护性 | 修改影响面大 | 仅需修改中介者 |
| 扩展性 | 需修改所有调用方 | 新增模块只需注册 |
| 典型应用场景 | 简单系统 | 复杂交互系统 |
3. 实战:电商系统改造实录
3.1 原始架构痛点
原有系统存在订单模块直接调用库存、支付、物流等6个模块的情况,导致:
- 修改支付接口需要同步更新5个调用方
- 循环依赖导致启动顺序敏感
- 新增促销模块需要修改3个现有模块
3.2 中介者实现关键代码
// 抽象中介者 public interface OrderMediator { void register(ModuleType type, OrderModule module); void notify(ModuleType sender, Event event); } // 具体中介者 public class OrderMediatorImpl implements OrderMediator { private Map<ModuleType, OrderModule> modules = new HashMap<>(); @Override public void notify(ModuleType sender, Event event) { switch (event.getType()) { case ORDER_CREATED: modules.get(ModuleType.INVENTORY).handle(event); modules.get(ModuleType.PAYMENT).handle(event); break; case PAYMENT_COMPLETED: modules.get(ModuleType.LOGISTICS).handle(event); break; // 其他事件处理... } } }3.3 改造效果对比
| 指标 | 改造前 | 改造后 |
|---|---|---|
| 模块间依赖数 | 23 | 6 |
| 新增模块工作量 | 3人日 | 0.5人日 |
| 接口变更影响范围 | 5-8个文件 | 仅中介者类 |
4. 高级应用技巧
4.1 中介者模式与消息队列的配合
在分布式系统中,可以结合RabbitMQ实现跨服务中介:
- 各服务订阅特定事件类型
- 中介者服务将事件发布到对应Exchange
- 通过RoutingKey实现精确路由
# Django示例:使用Celery作为中介者 @app.task def order_mediator(event_type, payload): if event_type == 'order_created': inventory_task.delay(payload) payment_task.delay(payload) elif event_type == 'payment_success': logistics_task.delay(payload)4.2 性能优化方案
对于高频交互场景:
- 采用事件批处理(如每100ms处理一次)
- 使用享元模式共享事件对象
- 异步非阻塞处理(Reactor模式)
5. 避坑指南
5.1 典型误用场景
- 过度集中化:将业务逻辑全部塞进中介者,导致"上帝对象"
- 正确做法:中介者只做路由,业务逻辑仍在各模块
- 循环通知:A模块事件触发B模块,B又触发A
- 解决方案:设置事件最大传播深度
- 同步阻塞调用:影响系统吞吐量
- 改进方案:结合观察者模式异步处理
5.2 调试技巧
- 在中介者添加事件日志:
class LogisticsMediator { notify(sender, event) { console.log(`[${new Date().toISOString()}] ${sender} -> ${event.type}`); // ...原有逻辑 } }- 使用染色标记追踪事件流
- 可视化事件流向图(可用GraphQL实现)
6. 模式演进与替代方案
6.1 中介者模式变种
- 事件总线:简化版中介者,如Vue的EventBus
- CQRS模式:将读写操作分离为不同中介者
- Saga模式:分布式事务场景下的中介者实现
6.2 与其他模式对比
当遇到以下情况时考虑替代方案:
- 简单交互 → 观察者模式
- 需要历史记录 → 备忘录模式
- 固定处理流程 → 责任链模式
在最近开发的物联网平台中,我们采用分层中介者架构:设备层使用本地中介者处理实时控制,业务层通过Kafka实现全局事件协调。这种混合架构既保证了实时性,又实现了模块间解耦,使系统能够支持每天200万+的设备消息处理。
