代码界的「和事佬」:中介者模式的调解艺术
一、当对象开始「微信轰炸」
你是否见过这样的代码修罗场?
订单模块直接调用支付模块的私有方法;
用户服务硬编码依赖邮件服务的接口;
物流系统与库存系统互相监听事件...
中介者模式就像代码世界的居委会大妈——「都别吵吵!有事找我登记!」 通过设立中央调解员,让相爱相杀的模块学会文明沟通,终结「对象互撕」的黑暗时代。
二、调解中心的施工蓝图(UML图)
┌─────────────┐ ┌─────────────┐
│ Colleague │ │ Mediator │
├─────────────┤ ├─────────────┤
│ +sendMsg() │─────────>│ +notify() │
│ +recvMsg() │<─────────┤ │
└──────△──────┘ └──────△──────┘
│ │
┌──────┴──────┐ ┌──────┴──────┐
│ Concrete │ │ Concrete │
│ Colleague │ │ Mediator │
└─────────────┘ └─────────────┘
- 暴躁邻居(Colleague):需要沟通的模块
- 居委会大妈(Mediator):中央协调员
- 301住户(ConcreteColleague):具体业务模块
- 王大妈(ConcreteMediator):具体协调逻辑
三、代码社区的和谐改造(场景实战)
1. 创建社区住户(同事类)
// 住户接口(所有模块必须遵守社区公约)
interface Module {
void send(String message, String target); // 通过居委会传话
void receive(String message, String sender); // 接收调解后的信息
String getModuleName(); // 模块身份证
}
// 具体住户:订单模块
class OrderModule implements Module {
public void send(String msg, String target) {
CommunityMediator.relay(this, msg, target);
}
public void receive(String msg, String sender) {
System.out.println("📦 订单模块收到【" + sender + "】消息:" + msg);
}
public String getModuleName() { return "订单模块"; }
}
// 具体住户:支付模块
class PaymentModule implements Module { /* 类似实现 */ }
2. 成立居委会(中介者)
class CommunityMediator {
private static Map<String, Module> modules = new HashMap<>();
// 住户登记(模块注册)
public static void register(Module module) {
modules.put(module.getModuleName(), module);
}
// 消息转发(含智能过滤)
public static void relay(Module sender, String rawMsg, String target) {
String filteredMsg = filterMessage(rawMsg);
if ("全体住户".equals(target)) {
broadcast(sender, filteredMsg);
} else {
Module receiver = modules.get(target);
if (receiver != null) {
System.out.println("📮 居委会传话:【"
+ sender.getModuleName() + "】→【" + target + "】");
receiver.receive(filteredMsg, sender.getModuleName());
}
}
}
// 敏感词过滤(维持社区和谐)
private static String filterMessage(String msg) {
return msg.replace("崩溃了", "暂时不可用")
.replace("垃圾代码", "历史遗留代码");
}
// 社区广播(@全体成员)
private static void broadcast(Module sender, String msg) {
modules.values().forEach(m -> {
if (m != sender) m.receive(msg, sender.getModuleName());
});
}
}
3. 社区和谐生活演示
public class HappyCommunity {
public static void main(String[] args) {
// 住户登记
Module order = new OrderModule();
Module payment = new PaymentModule();
Module inventory = new InventoryModule();
CommunityMediator.register(order);
CommunityMediator.register(payment);
CommunityMediator.register(inventory);
// 文明沟通示例
order.send("订单123已创建,请准备扣款", "支付模块");
payment.send("扣款成功,请发货", "库存模块");
inventory.send("全体注意:数据库即将维护", "全体住户");
}
}
四、调解模式 vs 菜市场骂街
| 维度 | 中介者模式 | 直接调用 |
|---|---|---|
| 耦合度 | 模块只依赖中介(松耦合) | 模块互相依赖(紧耦合) |
| 复杂度 | 集中管理通信逻辑 | 网状依赖难以维护 |
| 扩展性 | 新增模块只需注册 | 需修改所有相关模块 |
| 可维护性 | 通信逻辑统一维护 | 散落在各个角落 |
| 现实类比 | 10086客服中心 | 用户直接互打电话 |
五、代码社区的和谐案例
- 聊天服务器:用户消息统一由服务端转发
- 机场调度系统:塔台协调所有飞机的起降
- GUI事件管理:对话框组件通过管理器交互
- 微服务网关:统一处理服务间通信和鉴权
- 游戏引擎:角色、道具、场景通过事件中心交互
经典案例:
Spring Cloud Gateway 就是微服务世界的中介者,优雅处理路由、限流和认证。
六、防邻里纠纷指南
- 避免全能中介
// 错误示范:中介者处理业务逻辑
class GodMediator {
void processOrder() { /* 既当裁判又当球员 */ }
}
- 消息协议标准化
// 定义社区通信规范
record CommunityMessage(
String sender,
String receiver,
MessageType type,
String content
) {}
- 分级中介系统
// 分楼栋设立调解员
class BuildingMediator extends CommunityMediator {
// 处理本楼栋事务
}
- 防止消息风暴
// 消息频率限制
if (messageCount.get() > 1000) {
throw new RateLimitException("消息太频繁!");
}
- 死锁检测机制
// 检测循环依赖
if (detectCircularDependency(sender, receiver)) {
throw new MediationException("检测到循环依赖!");
}
七、社区文明公约
中介者模式让代码成为优雅的社区管家:
- ✅ 要:用于多模块复杂交互的场景
- ✅ 要:通过中介实施统一通信策略
- ❌ 不要:让中介者变成全能上帝
- ❌ 不要:在简单场景强行调解
当你在Spring中优雅使用ApplicationEventPublisher时,请想起中介者模式——那个默默守护模块和谐共处的数字居委会!