中介者模式
引言
在软件系统中,当多个对象(如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系统、分布式协调等场景中,中介者模式能显著提升系统可维护性和扩展性,成为架构设计中的"交互指挥官"。