Appearance
中介者模式(Mediator Pattern)笔记
定义
中介者模式是一种行为设计模式,它定义一个对象来封装一组对象之间的交互,使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
英文原文定义:
The Mediator Pattern defines an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
核心概念
中介者模式通过引入中介者对象来管理对象间复杂的交互关系,将网状结构变为星型结构,降低了对象间的直接耦合。
主要角色
- Mediator(抽象中介者):定义同事对象到中介者对象的接口
- ConcreteMediator(具体中介者):协调各同事对象实现协作行为
- Colleague(抽象同事类):定义各同事类公有方法,维持对中介者的引用
- ConcreteColleague(具体同事类):实现自身业务逻辑,通过中介者与其他同事通信
优缺点
优点
- 降低耦合度:将对象间多对多关系转化为一对多关系
- 简化对象协议:用中介者和同事间的一对多交互替代多对多交互
- 集中控制:将交互复杂性集中到中介者中
- 复用性提高:各同事类可被独立复用
- 开闭原则:新增中介者无需修改现有代码
缺点
- 中介者可能复杂:随着交互逻辑增加,中介者可能变得过于复杂
- 性能瓶颈:中介者可能成为系统性能瓶颈
- 过度集中:过度使用可能导致中介者承担过多责任
- 调试困难:交互逻辑集中在中介者中可能使调试复杂化
解决的问题
中介者模式主要解决以下经典问题:
- 复杂对象引用:对象间存在大量复杂关联关系时
- 交互逻辑分散:对象间交互行为分散在各个对象中难以维护时
- 复用困难:由于对象间强耦合导致难以独立复用时
- 分布式通信:需要集中管理对象间通信时
- UI组件协调:GUI中各组件需要复杂协调时
实现注意事项
中介者职责边界:
- 明确中介者只负责协调,不承担业务逻辑
- 避免中介者成为"上帝对象"
同事类设计:
- 同事类应保持对中介者的弱引用
- 同事类间不应有直接依赖
接口设计:
- 定义清晰的中介者接口
- 避免中介者接口过于臃肿
性能考量:
- 对于高频交互系统,考虑中介者性能影响
- 可能需要引入缓存或异步机制
错误处理:
- 设计良好的错误传播机制
- 避免中介者成为单点故障
实现变体
事件驱动中介者:
- 使用观察者模式实现松散耦合
- 同事通过事件与中介者通信
命令总线模式:
- 将请求封装为命令对象
- 中介者作为命令总线分发命令
微内核架构:
- 中介者作为系统核心
- 各功能作为插件与核心通信
面向消息中介:
- 基于消息队列实现中介
- 支持异步和分布式通信
与其他模式的关系
相似模式区分
观察者模式:
- 中介者:集中处理同事对象间双向交互
- 观察者:处理对象间单向通知关系
门面模式:
- 中介者:协调平等对象间的交互
- 门面:为子系统提供统一接口
代理模式:
- 中介者:协调多个对象间关系
- 代理:控制对一个对象的访问
常见搭配组合
- 中介者 + 观察者:实现事件驱动架构
- 中介者 + 命令:封装请求为命令对象
- 中介者 + 组合:处理复杂组件结构
- 中介者 + 享元:共享无状态的同事对象
典型应用场景
- 聊天应用程序(聊天室作为中介者)
- 航空交通管制系统
- GUI组件交互(如表单验证)
- 分布式系统协调
- 工作流引擎
- 多玩家游戏系统
- 企业服务总线(ESB)
代码示例(聊天室实现)
java
// 抽象中介者
interface ChatMediator {
void sendMessage(String msg, User user);
void addUser(User user);
}
// 具体中介者:聊天室
class ChatRoom implements ChatMediator {
private List<User> users = new ArrayList<>();
@Override
public void sendMessage(String msg, User user) {
for (User u : users) {
// 不发送给消息发起者
if (u != user) {
u.receive(msg);
}
}
}
@Override
public void addUser(User user) {
this.users.add(user);
}
}
// 抽象同事类
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 abstract void receive(String msg);
}
// 具体同事类
class ChatUser extends User {
public ChatUser(ChatMediator med, String name) {
super(med, name);
}
@Override
public void send(String msg) {
System.out.println(this.name + " 发送: " + msg);
mediator.sendMessage(msg, this);
}
@Override
public void receive(String msg) {
System.out.println(this.name + " 收到: " + msg);
}
}
// 客户端代码
public class ChatClient {
public static void main(String[] args) {
ChatMediator mediator = new ChatRoom();
User john = new ChatUser(mediator, "John");
User jane = new ChatUser(mediator, "Jane");
User doe = new ChatUser(mediator, "Doe");
mediator.addUser(john);
mediator.addUser(jane);
mediator.addUser(doe);
john.send("Hi everyone!");
jane.send("Hello John!");
}
}