中介者模式案例

wen java案例 3

**
《中介者模式实战案例拆解:从多对象混乱交互到优雅解耦的架构之美》

中介者模式案例


目录导读

  1. 为什么需要中介者模式?——认识“对象爆炸”困境
  2. 经典案例解析:聊天室、机场塔台与订单系统
  3. 中介者模式核心结构:角色职责与协作流程
  4. 代码实战:用Python实现一个可扩展的中介者框架
  5. 模式对比:中介者 vs 观察者 vs 门面模式(含决策指南)
  6. 常见陷阱与性能优化:事件风暴与延迟问题
  7. 问答环节:高频面试题与架构设计争议解答

为什么需要中介者模式?
在复杂的业务系统中,多个对象(Colleague)相互通信极易形成“蛛网状”依赖,一个电商订单流程中,库存服务、支付服务、物流服务、通知服务彼此直接调用,新增一个“优惠券服务”时,需要修改所有关联对象的代码,耦合度呈指数级增长,中介者模式(Mediator Pattern)通过引入一个中央调度器,将对象间的“多对多”关系转化为“一对多”与“多对一”的星型结构,使对象不再显式引用彼此,从而降低系统维护成本。

经典案例解析

  • 聊天室系统:用户(Colleague)之间不直接发消息,而是通过聊天室服务器(Mediator)转发,新增“禁言”或“消息过滤”功能只需修改中介者,而用户类完全不变。
  • 机场塔台调度:飞机(Colleague)之间不协商航线,全部向塔台(Mediator)报告位置与意图,由塔台统一分配跑道,这避免了飞机间的直接通信造成的冲突。
  • 订单状态协同:订单创建后,中介者依次触发库存扣减、支付接口调用、物流单生成,任一环节失败可统一回滚,而各服务无需知道彼此的存在。

中介者模式核心结构

  • Mediator(抽象中介者):定义通信接口,如 send(message, colleague)
  • ConcreteMediator(具体中介者):维护并协调各Colleague的引用,实现协作逻辑。
  • Colleague(抽象同事类):持有中介者引用,只与中介者交互。
  • ConcreteColleague(具体同事类):实现自身业务,并通过中介者间接与其他同事通信。

代码实战:Python示例

from abc import ABC, abstractmethod
class Mediator(ABC):
    @abstractmethod
    def notify(self, sender, event, data=None): pass
class ChatRoom(Mediator):
    def __init__(self):
        self.users = []
    def add_user(self, user):
        self.users.append(user)
    def notify(self, sender, event, data=None):
        if event == "send":
            for user in self.users:
                if user != sender:
                    user.receive(data)
class User:
    def __init__(self, name, mediator):
        self.name = name
        self.mediator = mediator
    def send(self, msg):
        self.mediator.notify(self, "send", msg)
    def receive(self, msg):
        print(f"{self.name} 收到: {msg}")
# 使用
room = ChatRoom()
alice = User("Alice", room)
bob = User("Bob", room)
room.add_user(alice); room.add_user(bob)
alice.send("Hello!")

此代码中,新增一个“机器人User”无需修改原有用户类,只需传给同一个ChatRoom实例。

模式对比

  • 中介者 vs 观察者:观察者是一对多的事件广播,而中介者处理多对多的复杂业务编排,例如UI按钮(观察者)只触发“点击”事件,而窗口(中介者)协调按钮、文本框、列表的互斥状态。
  • 中介者 vs 门面:门面提供统一接口,但不参与业务逻辑;中介者封装了交互行为本身,门面是“入口”,中介者是“大脑”。

常见陷阱与性能优化

  • 上帝对象:中介者逻辑过于庞大时,应拆分为多个专门化中介者(如订单中介者、库存中介者)。
  • 事件风暴:高频消息导致阻塞时,可引入异步队列(如RabbitMQ)或使用事件源(Event Sourcing)模式,将中介者改为“事件旋转器”。
  • 延迟性:若中介者同步调用多个远程服务,会拉长响应时间,建议用“补偿事务”配合超时机制。

问答环节
Q1:中介者模式与“迪米特法则”有何关系?
A1:中介者强制了“最少知道原则”,每个对象只认识中介者,从而减少是朋友类的数量,降低依赖脆弱性。

Q2:为什么Nginx的反向代理也是中介者模式的体现?
A2:客户端不直接请求后端多台服务器,而是请求Nginx(中介者),由它转发到具体节点并返回结果,这实现了“对象”(服务器)的解耦,并支持负载均衡(中介者的扩展功能)。

Q3:如果中介者崩溃,系统会怎样?如何容灾?
A3:所有间接通信将中断,容灾方案包括:中介者集群(如ZooKeeper协调下的多实例)、失败时降级为直连模式(保留原直连接口作为Fallback)。



中介者模式并非万灵药,它适合“交互规则频繁变化”的场景,当对象关系简单时,盲目引入中介者反而增加理解成本,在微服务架构中,API网关、消息队列(如Kafka)实质上都是分布式中介者,掌握其思想并灵活变通,你将在架构设计时多一张制胜王牌。

抱歉,评论功能暂时关闭!