iOS 設計模式的應用 ⑨ 中介者模式

前言

????在 App 中,我們常常遇到多個 UI 元素之間相互依賴,比如當列表框中的某一項被選中時,UILabel 會被更新為列表框中選定的值。又或者當用戶在文本框輸入了新的值時,需要將這個新的值加入到列表框的列表中。當更多的 UI 元素參與到這一錯綜復雜的關系之中時,情況可能變得難以控制,元素之間需要彼此了解并相互操作。又或者當從一個頁面跳轉到另一個頁面時,需要了解目標頁面所需參數等等。這個時候需要有一個集中化的角色組織各種 UI 元素在同一個語境下進行交互,稱之為中介者(Mediator)。

什么是中介者模式

????在面向對象的設計中鼓勵把行為分散到不同對象中,這種分散可能導致對象之間的互相聯系。在最糟糕的情況下,所有對象都彼此了解并相互操作。雖然把行為分散到不同對象增強了可復用性,但是增加的相互關聯又減少了獲得的益處。在這種情況下就需要中介者模式。中介者模式提供了一個中介類作為集中的場所,用一個中介對象來封裝一系列的對象交互,中介者使各對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。

中介者模式的類圖.png

什么時候使用中介者模式

  • 對象之間的交互雖然定義明確但是非常復雜,導致一組對象彼此相互依賴,形成了網狀結構。若一個對象發生改變,我們也需要跟蹤與之相關聯的對象,同時做出相應的處理。
  • 對象引用了許多其它對象并與其通訊,導致對象難以復用
  • 想要定制一個分布在多個類中的邏輯或行為,又不想生成太多子類。

中介者模式的優缺點

中介者模式的優點

  1. 降低了類的復雜度,將一對多轉化成了一對一。
  2. 各個類之間的解耦。
  3. 符合迪米特原則。(一個類對于其他類知道的越少越好)

中介者模式的缺點

隨著系統規模的增大,中介者會越來越龐大,變得復雜難以維護。

Cocoa 中的中介者模式

????UIViewController是一個抽象類,可以對其進行子類化以管理特定視圖。UIKit 框架還提供了UIViewController用于管理導航欄和工具欄對象的子類:UINavigationControllerUITabBarController. 一個 UITabController 可以管理多個 UINavigationController,而這些UINavigationController又可以管理一個或多個 UIViewController,每個控制器都有其關聯的視圖對象。除了管理視圖(包括覆蓋視圖)之外,視圖控制器還指定導航欄中顯示的按鈕和標題。

uictlr_object_diagram.jpeg

中介者模式的實現

運行時中介者模式的對象結構.png
  1. 定義中介者和對象遵守的協議

    @protocol Mediator;
    @protocol Colleague <NSObject>
    @property (nonatomic, strong) id <Mediator> mediator;
    - (void)receive;
    - (void)send;
    @end
      
    @protocol Mediator <NSObject>
    - (void)register:(id<Colleague>)colleague;
    - (void)relay:(id<Colleague>)cl;
    @end
    
    
  2. 實現其方法

    @interface ConcreteMediator : NSObject<Mediator>
    
    @end
    @interface ConcreteMediator ()
    @property (nonatomic, strong) NSMutableArray <id<Colleague>> *colleagues;
    @end
    @implementation ConcreteMediator
    - (NSMutableArray<id<Colleague>> *)colleagues{
        if (!_colleagues) {
            _colleagues = [NSMutableArray array];
        }
        return _colleagues;
    }
    - (void)register:(id<Colleague>)colleague{
        if ([colleague conformsToProtocol:@protocol(Colleague) ]){
            if(![self.colleagues containsObject:colleague]){
                [self.colleagues addObject:colleague];
                [colleague setMediator:self];
            }
        }
    }
    - (void)relay:(id<Colleague>)cl{
        for (id <Colleague> colleague  in self.colleagues) {
            if (![colleague isEqual:cl]) {
                [colleague  receive];
            }
        }
    }
    
    @end
    @interface ConcreteColleague1 : NSObject<Colleague>
    @end
    @implementation ConcreteColleague1
    
    @synthesize mediator;
    
    - (void)receive {
        NSLog(@"對象1收到消息");
    }
    
    - (void)send {
        NSLog(@"對象1發送消息");
        if (self.mediator) {
            [self.mediator relay:self];
        }
    }
    
    @end
    
    @interface ConcreteColleague2 : NSObject<Colleague>
    @end
    @implementation ConcreteColleague2
    @synthesize mediator;
    - (void)receive {
        NSLog(@"對象2收到消息");
    }
    - (void)send {
        NSLog(@"對象2發送消息");
        if (self.mediator) {
            [self.mediator relay:self];
        }
    }
    @end
    
  3. 最終調用對象方法時,會通過中介者進行管理、轉發。

    ConcreteMediator *mediator = [ConcreteMediator new];
    ConcreteColleague1 *colleague1 = [[ConcreteColleague1 alloc] init];
    ConcreteColleague2 *colleague2 = [[ConcreteColleague2 alloc] init];
    
    [mediator register:colleague1];
    [mediator register:colleague2];
    [colleague1 send];
    [colleague2 send];
    

總結

????雖然對于處理應用程序行為分散到不同對象并且對象相互依存的情況,中介者模式非常有用,但是應當避免讓中介者類過于龐大而難以維護。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 我們平時寫代碼的過程,一個類必然會與其他類產生依賴關系,如果這種依賴關系如網狀般錯綜復雜,那么必然會影響我們的代碼...
    不將就更好的你閱讀 459評論 0 4
  • 個人學習筆記分享,當前能力有限,請勿貶低,菜鳥互學,大佬繞道如有勘誤,歡迎指出和討論,本文后期也會進行修正和補充 ...
    Echo_YeZ閱讀 318評論 0 0
  • 何為中介者模式? 面向對象的設計鼓勵把行為分散到不同對象中,這種分散可能導致對象之間的相互關聯。在最糟糕的情況下,...
    泥孩兒0107閱讀 346評論 0 0
  • 一、特性與定義 1. 定義 定義一個中介對象來封裝一系列對象之間的交互,使原有對象之間耦合松散,且可以獨立地改變他...
    Vic_is_new_Here閱讀 1,679評論 0 5
  • 原文傳送門 1 介紹 中介者模式又稱為調停者模式,它是一種對象行為型模式。 1.1 什么是中介者模式 用一個中介對...
    dd299閱讀 114評論 0 1