【設計模式In Java】十六、中介者模式

中介者模式

定義

中介者模式(Mediator Pattern):用一箇中介對象(中介者)來封裝一系列的對象交互,中介者使各對象不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的交互。中介者模式又稱爲調停者模式,它是一種對象行爲型模式

場景

現在有一個Web系的用戶管理模塊,由於訪問量很大,會頻繁查詢用戶表,爲了減輕系統壓力,決定使用redis緩存用戶基本信息,在需要用戶基本信息時,直接從redis獲取,當緩存未命中時再從mysql數據庫讀取,並同步到redis;同時爲了分析用戶行爲,系統要求在用戶登錄的時候更新mysql數據庫最近登陸時間,並且向mongo寫入日誌信息。即系統中有3個協同對象:mysql、redis、mongo,這些對象之間有複雜的關係,對一個對象的操作可能同時影響其他幾個對象,這時候可以引入一個協調者——使用中介者模式,把所有對象上的操作交給中介去協調,對象自己只管做自己的操作,客戶端也只用操作關心的對象即可。

UML類圖

在這裏插入圖片描述

代碼

mediator
示例:

public class TestMediator {

    @Test
    public void test() {
        UserManager userManager = new UserManager();
        Mysql mysql = new Mysql(userManager);
        Mongo mongo = new Mongo(userManager);
        Redis redis = new Redis(userManager);

        userManager.setMongo(mongo);
        userManager.setMysql(mysql);
        userManager.setRedis(redis);

        System.out.println(redis.selectUser(1));
        System.out.println(redis.selectUser(1));
        System.out.println(redis.select(1));

        System.out.println();

        System.out.println(mysql.loginUser(new User(1, "Ashe")));

        System.out.println();

        System.out.println(mysql.updateUser(new User(1, "Zed")));

        System.out.println();

        System.out.println(redis.selectUser(1));
        
        /*
        select user info from redis...
        select user info from mysql...
        update redis user info...
        {"id":1,"username":"Ashe"}
        select user info from redis...
        {"id":1,"username":"Ashe"}
        select user info from redis...
        {"id":1,"username":"Ashe"}
        
        update mysql user login time...
        insert mongo user login time...
        {"id":1,"lastLoginTime":"2019-03-09T17:24:36.214","username":"Ashe"}
        
        update mysql user info...
        update redis user info...
        {"id":1,"username":"Zed"}
        
        select user info from redis...
        {"id":1,"username":"Zed"}
         */
    }

}

總結

看起來是使用外觀模式也是可以的,只要給這些子系統提供同一外觀即可,客戶端只關心調用的對象、調用的方法就好了,至於內部需要什麼邏輯,客戶端並不關心。但外觀模式用於子系統的聚合統一,他們之間並無邏輯上的聯繫,但是中介者模式主要用來協調各個對象的關係,多對多的關係讓中介者處理,在每個對象看來,就是一對一的關係——只跟中介者產生聯繫。

如果現在又加了另外的數據源怎麼辦,有兩種方法來做出調整:第一種是直接在AbstractUserManager中新增這種數據源的引用,然後對UserManager中相關的業務方法做出修改,客戶端也許在構造UserManager時做出修改;另外一種是直接添加一個新的子類NewUserManager繼承UserManager,在NewUserManager中添加新數據源的引用,並對覆蓋需要調整的業務方法,同樣客戶端需要做出相應的修改。這兩種方法前者違背開閉原則,後者相對遵守開閉原則,但假設修改頻繁,可能會導致產生很多的子類,維護起來很困難。

中介者模式的主要優點如下:

  • 中介者模式簡化了對象之間的交互,它用中介者和同事的一對多交互代替了原來同事之間的多對多交互,一對多關係更容易理解、維護和擴展,將原本難以理解的網狀結構轉換成相對簡單的星型結構。
  • 中介者模式可將各同事對象解耦。中介者有利於各同事之間的鬆耦合,我們可以獨立的改變和複用每一個同事和中介者,增加新的中介者和新的同事類都比較方便,更好地符合“開閉原則”。
  • 可以減少子類生成,中介者將原本分佈於多個對象間的行爲集中在一起,改變這些行爲只需生成新的中介者子類即可,這使各個同事類可被重用,無須對同事類進行擴展。

中介者模式的主要缺點如下:

  • 在具體中介者類中包含了大量同事之間的交互細節,可能會導致具體中介者類非常複雜,使得系統難以維護。

在以下情況下可以考慮使用中介者模式:

  • 系統中對象之間存在複雜的引用關係,系統結構混亂且難以理解。
  • 一個對象由於引用了其他很多對象並且直接和這些對象通信,導致難以複用該對象。
  • 想通過一箇中間類來封裝多個類中的行爲,而又不想生成太多的子類。可以通過引入中介者類來實現,在中介者中定義對象交互的公共行爲,如果需要改變行爲則可以增加新的具體中介者類。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章