在一個項目裏,程序由大量的類來組成。隨着功能的不斷增長,類和類之間的依賴關係也跟着趨於複雜,而中介者模式便能解決這個問題。 中介者模式,是用一個對象來封裝一組或一系列對象的交互方式,使對象間的交互能夠在一箇中介者對象中處理,從而使各對象耦合鬆散,並且能夠獨立的改變它們之間的交互。前端
中介者比如站在十字路口的交通警察。若是改變十字路口的交通模式,只須要把新的交通策略給交通警察便可,而不是路上的全部車輛,這樣才能更好的協調來自不一樣方向車輛。markdown
一、鬆散耦合oop
中介者模式經過把多個同事對象之間的交互封裝到中介對象裏面,從而使得同時對象之間鬆散耦合,基本上能夠作到互不依賴。這樣一來,同時對象就能夠獨立的變化和複用,再也不「牽一髮動全身」。優化
二、集中控制交互atom
多個同事對象的交互,被封裝在中介者對象裏面集中管理,使得這些交互行爲發生變化的時候,只須要修改中介者就能夠了。spa
三、多對多變爲一對多設計
沒有中介者模式的時候,同事對象之間的關係一般是多對多,引入中介者對象後,中介者和同事對象的關係一般變爲雙向的一對多,這會讓對象的關係更容易理解和實現。code
一、Mediator:抽象中介者 在裏面定義各個同事之間交互須要的方法,能夠是公共的通訊方法,也能夠是小範圍的交互方法。 二、ConcreteMeditor:具體中介者 它須要瞭解並維護各個同事對象,並負責具體的協調各同事對象的交互關係。 三、Colleague:抽象同事類 主要約束同事對象的類型,並實現一些具體同事類之間的公共功能,好比,每一個具體同事類都應該知道中介者對象,也就是具體同事類都會持有中介者對象,均可以到這個類裏面。 四、ConcreteColleague:具體同事類 實現本身的業務,須要與其餘同事通訊時候,就與持有的中介者通訊,中介者會負責與其餘同事類交互。orm
MVC中的C(controller)就是一箇中介者,它的做用就是把M和V隔離開,協調M和V協同工做,把M運行的結果和V表明的視圖融合成一個前端能夠展現的頁面,減小M和V的依賴關係。對象
iOS中的UINavigationController就是一箇中介者,他來管理視圖的跳轉。通常狀況下,一個頁面便對應代碼中的一個VC,而一箇中等規模的軟件至少會有幾十個的頁面,對應的就是幾十個VC。要管理這些VC之間的關係是一件很是繁瑣的事情,每當一個VC要跳轉到另外個VC,咱們須要包含新的VC的頭文件,因而有的起銜接做用的VC中包含了大量的其餘VC的頭文件。使用中介者模式能夠很是好地去解決這個問題。
下面就以此爲例,說明中介者模式的應用
需求描述:在一個根視圖控制器中(暫且稱之爲rootVC),點擊不一樣的按鈕,跳到對應的視圖控制器,分別是firstVC、secondVC、thirdVC。
傳統作法策略圖 從圖中看到,這樣的處理方式繁亂複雜,不夠清晰,當控制器VC數量很是多時,更加難以維護。
中介者模式策略圖 從圖中能夠直觀感覺到,處理方式簡潔明瞭。Mediator類的做用就至關於一個路由器,將客戶發起的URL請求轉移到對應的類。
下面來設計這個類
中介者,在應用程序整個生命週期應該只有一個實例,不然將沒法管理多個對象間的交互,因此這裏要使用單例來實現它的建立。這個過程就略過了,直接看重點部分。 首先添加2個控制器屬性,一個表示用於發起跳轉動做的控制器;另外一個表示目的控制器。 在類的.h文件裏,聲明屬性、方法。
@interface Mediator : NSObject
@property (nonatomic, strong, readonly) ViewController *rootVC;
@property (nonatomic, strong, readonly) UIViewController *activeVC;
// 單例建立類方法
+ (MediatorManager *)sharedManager;
// 外界跳轉調用方法
- (void)jumpToNewViewController:(id)tagValue;
@end
複製代碼
在.m文件裏面 導入全部須要跳轉的控制器頭文件
#import "ViewController.h"
#import "FirstViewController.h"
#import "SecondViewController.h"
#import "ThirdViewController.h"
複製代碼
實現跳轉方法,根據傳入的參數,決定跳轉到哪一個控制器VC
- (void)jumpToNewViewController:(id)tagValue{
if ([tagValue isKindOfClass:[NSNumber class]]) {
switch ([tagValue integerValue]) {
case 1:
{
FirstViewController *firstVC = [[FirstViewController alloc] init];
_activeVC = firstVC;
[self.rootVC.navigationController pushViewController:firstVC animated:YES];
}
break;
case 2:
{
SecondViewController *secondVC = [[SecondViewController alloc] init];
_activeVC = secondVC;
[self.rootVC.navigationController pushViewController:secondVC animated:YES];
}
break;
case 3:
{
ThirdViewController *thirdVC = [[ThirdViewController alloc] init];
_activeVC = thirdVC;
[self.rootVC.navigationController pushViewController:thirdVC animated:YES];
}
break;
default: // 其餘狀況,默認返回
_activeVC = self.rootVC;
[self.rootVC.navigationController popViewControllerAnimated:YES];
break;
}
}
}
複製代碼
這裏,能夠再優化一點,把各控制器VC對應標識符統一放在枚舉變量裏,方便管理。
typedef NS_ENUM(NSInteger, ButtonTag) {
TagFirstVC = 1,
TagSecondVC = 2,
TagThirdVC = 3,
};
複製代碼
中介者模式的應用不光用在VC的管理,當功能中出現了相似「多對多」的複雜的對象羣時,就能夠用到它來管理這些對象。 固然,在此以前,須要考慮的不該該是開始使用中介者模式,而是考慮這個功能的設計是否合理。 另外,使用中介者模式雖然下降了各個對象之間的耦合,減小了對象之間邏輯的複雜度,可是這個複雜度在必定程度上轉移到了Mediator類中,所以Mediator類的功能維護須要謹慎處理。