Skip to content

中介者模式

引言

在软件系统中,当多个对象(如UI组件、微服务)需高频交互时,直接通信会导致网状耦合(如聊天室中用户相互引用)。中介者模式通过引入协调中枢,将多对多交互转为一对多管理,成为解耦复杂交互关系的核心设计模式。

诞生背景

GoF在《设计模式》中提出中介者模式,解决三大痛点:

  • 关系混乱:对象间直接引用形成蜘蛛网结构(如10个UI组件相互调用)
  • 复用困难:对象因强耦合无法独立重用
  • 变更失控:修改一个对象引发连锁更新

典型案例:航空管制系统(飞机间不直接通信,全部通过塔台调度)

演进过程

  • GoF基础(1994):确立中介者、同事对象核心角色
  • 企业级演进:消息中间件(如Kafka、RabbitMQ)成为分布式中介者
  • 现代应用:前端状态管理库(Redux Store/Vuex)协调组件通信

核心概念

  • 中介者(Mediator)
    • 定义对象间交互协议的抽象接口
  • 具体中介者(ConcreteMediator)
    • 实现协调逻辑,持有同事对象引用
  • 同事对象(Colleague)
    • 仅与中介者通信,不感知其他对象

通用实现

Java 实现

java
// 抽象中介者
interface ChatMediator {
    void sendMessage(String msg, User user);
}

// 具体中介者
class ChatRoom implements ChatMediator {
    @Override
    public void sendMessage(String msg, User user) {
        System.out.println(user.getName() + " 发送: " + msg);
    }
}

// 同事对象
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 String getName() { return name; }
}

// 具体同事类
class ChatUser extends User {
    public ChatUser(ChatMediator med, String name) {
        super(med, name);
    }
    
    @Override
    public void send(String msg) {
        mediator.sendMessage(msg, this);
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        ChatMediator mediator = new ChatRoom();
        User user1 = new ChatUser(mediator, "Alice");
        User user2 = new ChatUser(mediator, "Bob");
        
        user1.send("你好!");  // 输出: Alice 发送: 你好!
        user2.send("收到!");  // 输出: Bob 发送: 收到!
    }
}

PHP 实现

php
// 抽象中介者
interface ControlTower {
    public function requestLanding(Airplane $plane);
}

// 具体中介者
class AirportTower implements ControlTower {
    public function requestLanding(Airplane $plane) {
        echo $plane->getName() . " 获准降落\n";
    }
}

// 同事对象
class Airplane {
    private ControlTower $tower;
    private string $name;
    
    public function __construct(ControlTower $tower, string $name) {
        $this->tower = $tower;
        $this->name = $name;
    }
    
    public function requestLand() {
        $this->tower->requestLanding($this);
    }
    
    public function getName(): string {
        return $this->name;
    }
}

// 客户端
$tower = new AirportTower();
$flight1 = new Airplane($tower, "CA123");
$flight2 = new Airplane($tower, "UA456");

$flight1->requestLand();  // 输出: CA123 获准降落
$flight2->requestLand();  // 输出: UA456 获准降落

应用场景

  • GUI组件交互:表单控件验证(输入框/按钮通过中介者协调)
  • 分布式协调:微服务架构中的消息中间件
  • 游戏开发:角色碰撞检测通过中介者处理
  • 工作流引擎:审批流程节点路由控制

案例:智能家居控制系统

Java 实现

java
// 中介者
class HomeAutomationMediator {
    private Light light;
    private Thermostat thermostat;
    
    public void setLight(Light light) { this.light = light; }
    public void setThermostat(Thermostat t) { this.thermostat = t; }
    
    public void goodMorning() {
        light.turnOn();
        thermostat.setTemperature(22);
        System.out.println("早安模式启动");
    }
}

// 同事对象
class Light {
    void turnOn() { System.out.println("灯光开启"); }
}

class Thermostat {
    void setTemperature(int temp) {
        System.out.println("温度设置为: " + temp + "°C");
    }
}

// 客户端
HomeAutomationMediator mediator = new HomeAutomationMediator();
Light light = new Light();
Thermostat thermo = new Thermostat();

mediator.setLight(light);
mediator.setThermostat(thermo);
mediator.goodMorning();

PHP 实现

php
// 中介者
class ECommerceMediator {
    private $inventory;
    private $payment;
    
    public function __construct(Inventory $inv, Payment $pay) {
        $this->inventory = $inv;
        $this->payment = $pay;
    }
    
    public function placeOrder(string $item) {
        if ($this->inventory->checkStock($item)) {
            $this->payment->process();
            echo "订单完成: $item\n";
        }
    }
}

// 同事对象
class Inventory {
    public function checkStock(string $item): bool {
        echo "检查库存: $item\n";
        return true;
    }
}

class Payment {
    public function process() {
        echo "支付处理中...\n";
    }
}

// 客户端
$inv = new Inventory();
$pay = new Payment();
$mediator = new ECommerceMediator($inv, $pay);
$mediator->placeOrder("手机");

优点

  • 解耦核心:对象间依赖降至最低(仅依赖中介者)
  • 简化交互:多对多关系转为一对多
  • 集中控制:交互逻辑收敛至单一位置
  • 复用性提升:同事对象可独立重用

缺点

  • 中介者膨胀:协调逻辑复杂化可能导致"上帝对象"
  • 性能瓶颈:高频交互场景中中介者可能成为单点瓶颈
  • 设计复杂度:需精准定义交互协议

扩展

  • 事件驱动中介者:同事对象通过事件通知中介者(如Spring ApplicationEvent)
  • 层级中介者:复杂系统分层协调(如全球航空管制→区域塔台)
  • 中介者集群:分布式场景下多中介者协同工作(如Kafka多Broker)

模式协作

  • 与观察者模式:中介者常用观察者实现消息传递
  • 与门面模式:门面封装子系统,中介者协调平等对象
  • 与状态模式:中介者可管理对象状态转换规则

延伸思考

  • 微服务架构:服务网格(如Istio)是中介者模式的云原生实践
  • 区块链应用:智能合约充当去中心化中介者协调交易
  • 过度设计风险:简单交互场景使用中介者反而增加复杂度

总结

中介者模式是复杂交互关系的解耦器,通过引入协调中枢将网状结构转为星型结构。其核心价值在于:交互逻辑的集中化管理对象间的高度解耦。在GUI系统、分布式协调等场景中,中介者模式能显著提升系统可维护性和扩展性,成为架构设计中的"交互指挥官"。