前言
????在 App 中,我們常常遇到多個(gè) UI 元素之間相互依賴,比如當(dāng)列表框中的某一項(xiàng)被選中時(shí),UILabel 會(huì)被更新為列表框中選定的值。又或者當(dāng)用戶在文本框輸入了新的值時(shí),需要將這個(gè)新的值加入到列表框的列表中。當(dāng)更多的 UI 元素參與到這一錯(cuò)綜復(fù)雜的關(guān)系之中時(shí),情況可能變得難以控制,元素之間需要彼此了解并相互操作。又或者當(dāng)從一個(gè)頁(yè)面跳轉(zhuǎn)到另一個(gè)頁(yè)面時(shí),需要了解目標(biāo)頁(yè)面所需參數(shù)等等。這個(gè)時(shí)候需要有一個(gè)集中化的角色組織各種 UI 元素在同一個(gè)語(yǔ)境下進(jìn)行交互,稱(chēng)之為中介者(Mediator)。
什么是中介者模式
????在面向?qū)ο蟮脑O(shè)計(jì)中鼓勵(lì)把行為分散到不同對(duì)象中,這種分散可能導(dǎo)致對(duì)象之間的互相聯(lián)系。在最糟糕的情況下,所有對(duì)象都彼此了解并相互操作。雖然把行為分散到不同對(duì)象增強(qiáng)了可復(fù)用性,但是增加的相互關(guān)聯(lián)又減少了獲得的益處。在這種情況下就需要中介者模式。中介者模式提供了一個(gè)中介類(lèi)作為集中的場(chǎng)所,用一個(gè)中介對(duì)象來(lái)封裝一系列的對(duì)象交互,中介者使各對(duì)象不需要顯式地相互引用,從而使其耦合松散,而且可以獨(dú)立地改變它們之間的交互。

什么時(shí)候使用中介者模式
- 對(duì)象之間的交互雖然定義明確但是非常復(fù)雜,導(dǎo)致一組對(duì)象彼此相互依賴,形成了網(wǎng)狀結(jié)構(gòu)。若一個(gè)對(duì)象發(fā)生改變,我們也需要跟蹤與之相關(guān)聯(lián)的對(duì)象,同時(shí)做出相應(yīng)的處理。
- 對(duì)象引用了許多其它對(duì)象并與其通訊,導(dǎo)致對(duì)象難以復(fù)用
- 想要定制一個(gè)分布在多個(gè)類(lèi)中的邏輯或行為,又不想生成太多子類(lèi)。
中介者模式的優(yōu)缺點(diǎn)
中介者模式的優(yōu)點(diǎn)
- 降低了類(lèi)的復(fù)雜度,將一對(duì)多轉(zhuǎn)化成了一對(duì)一。
- 各個(gè)類(lèi)之間的解耦。
- 符合迪米特原則。(一個(gè)類(lèi)對(duì)于其他類(lèi)知道的越少越好)
中介者模式的缺點(diǎn)
隨著系統(tǒng)規(guī)模的增大,中介者會(huì)越來(lái)越龐大,變得復(fù)雜難以維護(hù)。
Cocoa 中的中介者模式
????UIViewController是一個(gè)抽象類(lèi),可以對(duì)其進(jìn)行子類(lèi)化以管理特定視圖。UIKit 框架還提供了UIViewController用于管理導(dǎo)航欄和工具欄對(duì)象的子類(lèi):UINavigationController和UITabBarController. 一個(gè) UITabController 可以管理多個(gè) UINavigationController,而這些UINavigationController又可以管理一個(gè)或多個(gè) UIViewController,每個(gè)控制器都有其關(guān)聯(lián)的視圖對(duì)象。除了管理視圖(包括覆蓋視圖)之外,視圖控制器還指定導(dǎo)航欄中顯示的按鈕和標(biāo)題。

中介者模式的實(shí)現(xiàn)

-
定義中介者和對(duì)象遵守的協(xié)議
@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 -
實(shí)現(xiàn)其方法
@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(@"對(duì)象1收到消息"); } - (void)send { NSLog(@"對(duì)象1發(fā)送消息"); if (self.mediator) { [self.mediator relay:self]; } } @end @interface ConcreteColleague2 : NSObject<Colleague> @end @implementation ConcreteColleague2 @synthesize mediator; - (void)receive { NSLog(@"對(duì)象2收到消息"); } - (void)send { NSLog(@"對(duì)象2發(fā)送消息"); if (self.mediator) { [self.mediator relay:self]; } } @end -
最終調(diào)用對(duì)象方法時(shí),會(huì)通過(guò)中介者進(jìn)行管理、轉(zhuǎn)發(fā)。
ConcreteMediator *mediator = [ConcreteMediator new]; ConcreteColleague1 *colleague1 = [[ConcreteColleague1 alloc] init]; ConcreteColleague2 *colleague2 = [[ConcreteColleague2 alloc] init]; [mediator register:colleague1]; [mediator register:colleague2]; [colleague1 send]; [colleague2 send];
總結(jié)
????雖然對(duì)于處理應(yīng)用程序行為分散到不同對(duì)象并且對(duì)象相互依存的情況,中介者模式非常有用,但是應(yīng)當(dāng)避免讓中介者類(lèi)過(guò)于龐大而難以維護(hù)。