面向對象設計鼓勵將行為分散到各物件,但過度分散導致物件間相互引用爆炸(網狀結構),造成:
中介者模式引入中介者物件,將多對多轉為一對多(星型):同事物件只知中介者,不知彼此,由中介者統一協調轉發。
| 角色 | 職責 | 對應案例 |
|---|---|---|
| Mediator(抽象中介者) | 定義同事物件註冊、通訊介面 | UnitedNations |
| ConcreteMediator(具體中介者) | 實作協調邏輯,持有同事引用 | UnitedNationsSecurityCouncil |
| Colleague(抽象同事) | 持有中介者引用,定義通訊契約 | Country |
| ConcreteColleague(具體同事) | 實作業務邏輯,透過中介者通訊 | USA、China、Iraq |
// 抽象中介者
public abstract class UnitedNations {
protected final List<Country> countries = new ArrayList<>();
public void register(Country country) { countries.add(country); }
public void remove(Country country) { countries.remove(country); }
protected abstract void declare(Country country, String msg);
}
// 抽象同事
public abstract class Country {
protected final UnitedNations mediator;
protected final String name;
public Country(UnitedNations mediator, String name) {
this.mediator = mediator;
this.name = name;
}
public String getName() { return name; }
public abstract void declare(String msg); // 發送聲明
public abstract void receive(String msg); // 接收聲明
}
// 具體同事:各國
public class USA extends Country {
public USA(UnitedNations m, String name) { super(m, name); }
@Override public void declare(String msg) { mediator.declare(this, msg); }
@Override public void receive(String msg) { System.out.println("美國收到: [" + msg + "]"); }
}
public class China extends Country {
public China(UnitedNations m, String name) { super(m, name); }
@Override public void declare(String msg) { mediator.declare(this, msg); }
@Override public void receive(String msg) { System.out.println("中國收到: [" + msg + "]"); }
}
public class Iraq extends Country {
public Iraq(UnitedNations m, String name) { super(m, name); }
@Override public void declare(String msg) { mediator.declare(this, msg); }
@Override public void receive(String msg) { System.out.println("伊拉克收到: [" + msg + "]"); }
}
// 具體中介者:安理會邏輯
public class UnitedNationsSecurityCouncil extends UnitedNations {
@Override
protected void declare(Country country, String msg) {
for (Country c : countries) {
if (!c.equals(country)) { // 不發給自己
c.receive(country.getName() + " 溫和地說: " + msg);
}
}
}
}
public class Client {
public static void main(String[] args) {
UnitedNations un = new UnitedNationsSecurityCouncil();
Country usa = new USA(un, "美國");
Country china = new China(un, "中國");
Country iraq = new Iraq(un, "伊拉克");
un.register(usa);
un.register(china);
un.register(iraq);
usa.declare("我要打伊拉克,誰管我跟誰急!!!");
System.out.println("----------");
china.declare("我們強烈譴責!!!");
System.out.println("----------");
iraq.declare("來呀,來互相傷害呀!!!");
}
}
美國 溫和地說: 我要打伊拉克,誰管我跟誰急!!!
伊拉克收到: [美國 溫和地說: 我要打伊拉克,誰管我跟誰急!!!]
中國收到: [美國 溫和地說: 我要打伊拉克,誰管我跟誰急!!!]
----------
中國 溫和地說: 我們強烈譴責!!!
美國收到: [中國 溫和地說: 我們強烈譴責!!!]
伊拉克收到: [中國 溫和地說: 我們強烈譴責!!!]
----------
伊拉克 溫和地說: 來呀,來互相傷害呀!!!
美國收到: [伊拉克 溫和地說: 來呀,來互相傷害呀!!!]
中國收到: [伊拉克 溫和地說: 來呀,來互相傷害呀!!!]
| 模式 | 核心差異 | 適用場景 |
|---|---|---|
| 外觀模式 | 單向:外觀呼叫子系統,子系統不知外觀 | 簡化複雜子系統介面、解耦客戶端與內部結構 |
| 中介者模式 | 多向:同事雙向通訊,中介者協調 | 多物件複雜協作、需集中控制邏輯、避免網狀耦合 |
| 觀察者模式 | 一對多發布/訂閱,主題推送給觀察者 | 狀態變更通知、事件總線、解耦觸發與處理 |
符合以下特徵時,考慮中介者模式:
| 優點 | 缺點 |
|---|---|
|
|
使用 EventBus(Guava、Spring Event、MBassador)替代具體中介者:
eventBus.post(event))@Subscribe)這是中介者模式在現代架構中的演進形態。