1.1. 概述
在本文中,我们将了解 中介者模式(Mediator Pattern),它是 GoF(Gang of Four)提出的 23 种行为型设计模式之一。我们会解释它的设计初衷以及适用场景。
当然,也会通过一个实际的 Java 示例来演示其用法,帮助理解。
1.2. 中介者模式简介
在面向对象编程中,我们应始终追求 组件之间低耦合、高可复用性 的设计目标。这种设计方式使代码更易于维护和测试。
但在实际开发中,经常遇到多个对象之间高度依赖的复杂场景。这时,中介者模式就派上用场了。
中介者模式的核心思想是:通过引入一个中介对象来封装一组对象之间的交互逻辑,从而减少对象之间的直接依赖。所有对象之间的通信都通过中介者进行,而不是彼此直接调用。
这样做的好处是:
✅ 显著降低对象之间的耦合度
✅ 提高组件复用性
✅ 更容易维护和扩展系统逻辑
1.3. UML 结构图解析
下面是中介者模式的 UML 类图:
图中涉及以下角色:
- Mediator:定义同事类之间通信的接口
- Colleague:抽象类,持有对 Mediator 的引用
- ConcreteMediator:实现具体的交互逻辑
- ConcreteColleague1 & ConcreteColleague2:具体同事类,仅通过 Mediator 通信
关键点在于:同事类之间不直接通信,所有交互逻辑都由 Mediator 处理
这样设计带来的好处是:
- 同事类可以被轻松复用
- 修改交互逻辑只需改动 Mediator,无需修改同事类
1.4. Java 实现示例
1.4.1. 问题场景
假设我们要实现一个简单的冷却系统,包含以下组件:
- Button:按下按钮控制风扇开关
- Fan:风扇,需要先通电才能启动
- PowerSupplier:电源,负责供电
原始实现如下:
public class Button {
private Fan fan;
// constructor, getters and setters
public void press(){
if(fan.isOn()){
fan.turnOff();
} else {
fan.turnOn();
}
}
}
public class Fan {
private Button button;
private PowerSupplier powerSupplier;
private boolean isOn = false;
// constructor, getters and setters
public void turnOn() {
powerSupplier.turnOn();
isOn = true;
}
public void turnOff() {
isOn = false;
powerSupplier.turnOff();
}
}
public class PowerSupplier {
public void turnOn() {
// implementation
}
public void turnOff() {
// implementation
}
}
测试代码:
@Test
public void givenTurnedOffFan_whenPressingButtonTwice_fanShouldTurnOnAndOff() {
assertFalse(fan.isOn());
button.press();
assertTrue(fan.isOn());
button.press();
assertFalse(fan.isOn());
}
虽然功能正常,但可以看出 Button、Fan 和 PowerSupplier 之间耦合严重,不利于复用和扩展。
1.4.2. 引入中介者模式
我们引入一个中介者类来解耦:
public class Mediator {
private Button button;
private Fan fan;
private PowerSupplier powerSupplier;
// constructor, getters and setters
public void press() {
if (fan.isOn()) {
fan.turnOff();
} else {
fan.turnOn();
}
}
public void start() {
powerSupplier.turnOn();
}
public void stop() {
powerSupplier.turnOff();
}
}
修改其他类:
public class Button {
private Mediator mediator;
// constructor, getters and setters
public void press() {
mediator.press();
}
}
public class Fan {
private Mediator mediator;
private boolean isOn = false;
// constructor, getters and setters
public void turnOn() {
mediator.start();
isOn = true;
}
public void turnOff() {
isOn = false;
mediator.stop();
}
}
测试代码不变,仍然能正常运行:
@Test
public void givenTurnedOffFan_whenPressingButtonTwice_fanShouldTurnOnAndOff() {
assertFalse(fan.isOn());
button.press();
assertTrue(fan.isOn());
button.press();
assertFalse(fan.isOn());
}
✅ 现在:
- Button、Fan、PowerSupplier 之间不再直接通信
- 所有交互都通过 Mediator 完成
- 新增电源逻辑只需修改 Mediator,不影响其他类
1.5. 适用场景
中介者模式适用于以下情况:
- 系统中多个对象之间存在复杂依赖关系,难以维护
- 对象之间的交互逻辑集中化更有利于管理
- 想要遵循 单一职责原则 和 开闭原则
⚠️ 注意:如果对象之间耦合是因为设计不合理造成的,那应该优先重构类结构,而不是盲目使用中介者模式。
使用中介者模式前,应结合具体业务场景评估其适用性。
1.6. 小结
中介者模式通过引入一个中介对象来集中处理对象之间的交互逻辑,从而达到解耦、提升可维护性和扩展性的目的。
它适用于对象间交互复杂、关系多变的场景。但需要注意,它并不是解决所有耦合问题的“万能钥匙”,应结合具体场景合理使用。
完整代码可在 GitHub 上找到。