iT邦幫忙

2023 iThome 鐵人賽

DAY 25
0
Software Development

深入淺出設計模式 - 使用 C++系列 第 25

[Day 25] 集中對象間複雜的控制和溝通 — 中介者模式 (Mediator Pattern)

  • 分享至 

  • xImage
  •  

Intent

  • 中介者模式是一種行為設計模式,專門用於減少多個類 (稱為 "Colleagues") 之間的直接耦合。這是通過將這些類之間的通訊職責從類自身移除並集中轉移到一個稱為 "Mediator" 的中央單元來實現的
    • Before (取自: Ref[2])
      • https://ithelp.ithome.com.tw/upload/images/20231007/20138643qYXohWWVYk.jpg
    • After
      • https://ithelp.ithome.com.tw/upload/images/20231007/20138643pRuNIltD9I.jpg

[補充]: 星狀結構(Star Topology) vs. 網狀結構(Mesh Topology)

星狀結構

  • 在星狀結構中,所有的 Colleagues 都直接與一個中心點 (Mediator) 連接。這種結構的主要特點是簡單和集中式的控制
  • 適合的應用時機:
    • 簡單的系統架構: 當您需要一個簡單且容易管理的系統時
    • 高度集中的控制: 當所有的 Colleagues 都需要通過一個單一點進行協調時
    • 易於維護和擴展: 添加或刪除 Colleagues 不會影響到其他 Colleagues

網狀結構

  • 在網狀結構中,Colleagues 可能會直接與多個其他 Colleagues 連接,而不僅僅是與 Mediator 連接。這種結構更為複雜,但提供了更高的靈活性和健壯性
  • 適合的應用時機:
    • 複雜的系統架構: 當您有一個多層次或多組件的複雜系統時
    • 分散式控制: 當系統需要多個控制點或者當某些 Colleagues 需要直接與其他 Colleagues 互動時
    • 高可用性: 網狀結構通常更為健壯,因為它不完全依賴於一個中心點

Motivation

  • 當您有多個類並且它們之間有複雜的互動時,中介者模式特別有用
  • 例: 在 GUI 控件、網絡協議或者是多用戶應用程序中

Applicability

  • 複雜的互動: 用於減少多個類之間複雜的通訊
  • 可維護性: 用於提高系統的可維護性
  • 解耦: 當需要解耦一個系統的多個組件時

Structure

https://ithelp.ithome.com.tw/upload/images/20231007/20138643zWkgOeGVqg.png

Participants

  • Mediator: 這是一個接口,定義了各種不同類 (Colleagues) 之間通訊的機制。具體來說,它通常會有一個或多個方法,如 notify(),用於接收和轉發來自 Colleagues 的消息或事件
  • ConcreteMediator: 這是實現 Mediator 接口的類。它知道所有的 Colleagues 並且負責協調它們之間的互動
  • Colleague: 這些是參與到需要協調的活動中的各個類。它們不直接與其他 Colleagues 通訊,而是通過 Mediator 來進行
  • Client: 這是使用中介者模式的外部代碼。它負責創建所有的 Colleagues 和 Mediator,並可能會觸發整個協調過程

Collaborations

  • Client 與 Mediator: 客戶端創建一個具體的 Mediator 對象,並將其傳遞給所有的 Colleagues,以便它們能夠使用這個 Mediator 來協調互動
  • Colleague 與 Mediator: 每個 Colleague 都有一個對 Mediator 的引用。當一個 Colleague 需要與其他 Colleagues 互動(例如,發送或接收消息)時,它會使用這個 Mediator 對象。具體來說,Colleague 會調用 Mediator 的一個或多個方法來達成這一目的
  • Mediator 與 Colleagues: Mediator 使用它內部維護的 Colleagues 列表來協調各個 Colleagues 之間的互動。當 Mediator 收到一個來自某個 Colleague 的請求時,它會遍歷這個列表,並根據請求的性質來決定如何協調其他 Colleagues

這樣的協作機制允許我們將各個 Colleagues 的互動邏輯集中在 Mediator 中,從而達到減少系統耦合度和提高可維護性的目的

Consequences

優點

  • 減少耦合: Mediator 模式有助於減少系統中各個類之間的直接耦合,從而提高了系統的可維護性和可擴展性
  • 集中式管理: 由於所有的協調邏輯都集中在 Mediator 中,這使得更改或擴展這些邏輯變得相對容易
  • 靈活性: Mediator 模式允許動態地添加或刪除 Colleagues,這提供了很高的靈活性

缺點

  • 中介者的複雜性: 如果所有的協調邏輯都集中在一個 Mediator 中,這個 Mediator 可能會變得非常複雜和難以管理
  • 性能問題: 在某些情況下,過度使用 Mediator 可能會導致性能問題,因為每一次 Colleague 之間的互動都需要通過 Mediator
  • 過度集中: 雖然集中式管理有其優點,但它也可能導致過度集中,使得系統變得脆弱,特別是當 Mediator 出現問題時

Implementation (範例: 簡易聊天室通訊)

// Mediator Interface
class Mediator {
public:
    virtual void notify(const std::string& message, const std::string& colleague) = 0;
};

// Concrete Colleague
class Colleague {
private:
    Mediator* mediator;
    std::string name;
public:
    Colleague(Mediator* med, const std::string& n) : mediator(med), name(n) {}

    void send(const std::string& message) {
        mediator->notify(message, name);
    }
};

// Concrete Mediator
class ConcreteMediator : public Mediator {
private:
    std::vector<Colleague*> colleagues;
public:
    void addColleague(Colleague* colleague) {
        colleagues.push_back(colleague);
    }
    
    void notify(const std::string& message, const std::string& colleague) override {
        std::cout << colleague << " says: " << message << std::endl;
    }
};

int main() {
    ConcreteMediator mediator;
    Colleague alice(&mediator, "Alice");
    Colleague bob(&mediator, "Bob");
    mediator.addColleague(&alice);
    mediator.addColleague(&bob);

    alice.send("Hello, Bob!");
    bob.send("Hi, Alice!");
}

Known Uses

  • GUI Libraries: 在多數的 GUI 函式庫中,如 Java 的 Swing 或 Microsoft 的 WPF,通常會有一個專門的類 (如 Dialog 或 Panel) 來協調其內部控件 (如按鈕、文本框...等) 之間的互動
  • Workflow Engines: 在工作流引擎中,Mediator 模式常用於協調各個工作流程步驟之間的互動
  • Air Traffic Control Systems: 在航空交通控制系統中,Mediator 模式用於協調飛機、塔台和其他系統之間的通訊
  • Chat Applications: 在某些聊天應用中,尤其是那些需要高度模組化和可擴展性的,Mediator 模式可以用來協調用戶、聊天室和其他實體之間的消息傳遞

Reference

  1. https://refactoring.guru/design-patterns/mediator
  2. https://ianjustin39.github.io/ianlife/design-pattern/mediator-pattern/

上一篇
[Day 24] 以類別來表達文法規則 -解譯器模式 (Interpreter Pattern)
下一篇
[Day 26] 儲存系統的重要狀態 — 備忘錄模式 (Memento Pattern)
系列文
深入淺出設計模式 - 使用 C++37
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言