1. 意圖
用一個中介對象封裝一系列對象交互,使各對象不顯式相互引用,降低耦合,且可獨立改變交互行為。
2. 動機
面向對象設計鼓勵行為分布,但過度分布導致對象網狀耦合。最壞情況每個對象都知道所有其他對象。中介者將「多對多」轉為「一對多」,集中管理交互邏輯。
3. 適用性
- 一組對象以定義良好但復雜方式通信,依賴結構混亂。
- 一個對象引用很多其他對象並直接通信,難以復用。
- 想定制分布在多個類中的行為,不想生成大量子類。
4. 結構角色
| 角色 | 職責 |
| Mediator(中介者接口) | 定義同事對象通信接口。 |
| ConcreteMediator(具體中介者) | 實現協調邏輯,持有同事引用。 |
| Colleague(抽象同事類) | 持有中介者引用,通過中介者通信。 |
| ConcreteColleague(具體同事) | 實現具體行為,需與中介者交互時調用其方法。 |
5. 代碼示例(Java)
// 中介者接口
interface Mediator {
void register(Colleague c);
void send(String msg, Colleague from);
}
// 具體中介者
class ConcreteMediator implements Mediator {
private List<Colleague> colleagues = new ArrayList<>();
public void register(Colleague c) { colleagues.add(c); }
public void send(String msg, Colleague from) {
for (Colleague c : colleagues)
if (c != from) c.receive(msg);
}
}
// 抽象同事
abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator m) { mediator = m; }
public abstract void receive(String msg);
public void send(String msg) { mediator.send(msg, this); }
}
// 具體同事
class User1 extends Colleague {
public User1(Mediator m) { super(m); }
public void receive(String msg) { System.out.println("User1 收到: " + msg); }
}
class User2 extends Colleague {
public User2(Mediator m) { super(m); }
public void receive(String msg) { System.out.println("User2 收到: " + msg); }
}
// 測試
public class Test {
public static void main(String[] args) {
Mediator m = new ConcreteMediator();
Colleague u1 = new User1(m), u2 = new User2(m);
m.register(u1); m.register(u2);
u1.send("Hello"); // User2 收到: Hello
u2.send("World"); // User1 收到: World
}
}
6. Mediator vs Facade
| Mediator | Facade |
| 方向 | 多向(同事↔中介者↔同事) | 單向(Facade→子系統) |
| 目的 | 協調同事間交互 | 簡化子系統接口 |
| 耦合 | 同事只耦合中介者 | 子系統不依賴 Facade |
7. 相關模式
- Observer:同事可用觀察者模式與中介者通信(事件總線)。
- Facade:見上表對比。
8. 實戰場景
- GUI 對話框:按鈕、輸入框、列表框交互邏輯集中在 Dialog 類。
- 聊天室伺服器:用戶註冊、消息廣播由 Server(中介者)管理。
- 機場塔台:飛機(同事)只與塔台(中介者)通信,不直接聯繫其他飛機。
- Spring ApplicationContext:Bean 之間不直接引用,通過容器注入/事件發布交互。
- 上一篇文章: LeetCode 45:Jump Game II —— 貪心算法優化詳解
- 下一篇文章: UVA 10515:求 m^n 的個位數 — 規律 + 大數取模
Copyright ©
程式碼之家 All Rights Reserved