首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 設計模式精講:中介者模式實戰與聯合國安理會案例

     編輯:Java 相關知識

模式動機:從網狀到星型

面向對象設計鼓勵將行為分散到各物件,但過度分散導致物件間相互引用爆炸(網狀結構),造成:

  • 高耦合:修改一個物件牽一髮動全身
  • 低復用:物件離不開特定夥伴無法獨立工作
  • 難擴展:新增協作邏輯需修改多個類別

中介者模式引入中介者物件,將多對多轉為一對多(星型):同事物件只知中介者,不知彼此,由中介者統一協調轉發。

核心角色

角色職責對應案例
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("來呀,來互相傷害呀!!!");
    }
}

輸出結果


美國 溫和地說: 我要打伊拉克,誰管我跟誰急!!!
伊拉克收到: [美國 溫和地說: 我要打伊拉克,誰管我跟誰急!!!]
中國收到: [美國 溫和地說: 我要打伊拉克,誰管我跟誰急!!!]
----------
中國 溫和地說: 我們強烈譴責!!!
美國收到: [中國 溫和地說: 我們強烈譴責!!!]
伊拉克收到: [中國 溫和地說: 我們強烈譴責!!!]
----------
伊拉克 溫和地說: 來呀,來互相傷害呀!!!
美國收到: [伊拉克 溫和地說: 來呀,來互相傷害呀!!!]
中國收到: [伊拉克 溫和地說: 來呀,來互相傷害呀!!!]

模式對比與選型指南

模式核心差異適用場景
外觀模式單向:外觀呼叫子系統,子系統不知外觀簡化複雜子系統介面、解耦客戶端與內部結構
中介者模式多向:同事雙向通訊,中介者協調多物件複雜協作、需集中控制邏輯、避免網狀耦合
觀察者模式一對多發布/訂閱,主題推送給觀察者狀態變更通知、事件總線、解耦觸發與處理

適用性判斷清單

符合以下特徵時,考慮中介者模式:

  1. 一組物件以定義良好但複雜的方式通訊,產生難以理解的依賴結構
  2. 一個物件引用許多其他物件並直接通訊,導致難以復用
  3. 想定制分散在多個類別中的行為,但不想產生大量子類

優缺點總結

優點缺點
  • 降低同事物件耦合,易於獨立復用
  • 將協作邏輯集中化,便於維護與擴展
  • 將「物件行為」轉移為「物件交互」,提升系統宏觀可控性
  • 中介者可能變成「上帝類別」,邏輯過於龐大
  • 新增同事類型需修改中介者(違反開放封閉,可用觀察者緩解)
  • 間接層級增加,可能影響效能(通常可忽略)

現代化變體:事件總線作為中介者

使用 EventBus(Guava、Spring Event、MBassador)替代具體中介者:

  • 同事發布事件(eventBus.post(event))
  • 同事訂閱事件(@Subscribe)
  • 完全解耦發布者與訂閱者,支援異步、優先級、死信佇列

這是中介者模式在現代架構中的演進形態。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved