iOS 設(shè)計模式之十八(中介者模式)

一胆萧、概念

1、中介者模式的動機

? 現(xiàn)在QQ和微信基本是裝機必備APP俐东,就拿QQ來說跌穗,個人聊天可以一對一,假如多人聊天呢虏辫,那么就是多對多绽昏,用戶之間的關(guān)系就是一個網(wǎng)狀結(jié)構(gòu)菇爪,這個時候可以創(chuàng)建一個QQ群,這樣大家都可以進行交互。

? 在有些軟件中盈匾,某些類/對象之間的相互調(diào)用關(guān)系錯綜復(fù)雜,類似QQ用戶之間的關(guān)系泽西,此時佛纫,我們特別需要一個類似“QQ群”一樣的中間類來協(xié)調(diào)這些類/對象之間的復(fù)雜關(guān)系,以降低系統(tǒng)的耦合度稿黄。有一個設(shè)計模式正為此而誕生喊衫,它就是中介者模式

2杆怕、中介者模式的定義

? 中介者模式(Mediator Pattern):用一個中介對象(中介者)來封裝一系列的對象交互族购,中介者使各對象不需要顯式地相互引用,從而使其耦合松散陵珍,而且可以獨立地改變它們之間的交互寝杖。中介者模式又稱為調(diào)停者模式,它是一種對象行為型模式互纯。

? 通過引入中介者來簡化對象之間的復(fù)雜交互瑟幕,中介者模式是“迪米特法則”的一個典型應(yīng)用

3、中介者模式的4個角色

1)Mediator(抽象中介者):它定義一個接口只盹,該接口用于與各同事對象之間進行通信辣往。

2)ConcreteMediator(具體中介者):它是抽象中介者的子類,通過協(xié)調(diào)各個同事對象來實現(xiàn)協(xié)作行為殖卑,它維持了對各個同事對象的引用站削。

3)Colleague(抽象同事類):它定義各個同事類公有的方法,并聲明了一些抽象方法來供子類實現(xiàn)孵稽,同時它維持了一個對抽象中介者類的引用许起,其子類可以通過該引用來與中介者通信。

4)ConcreteColleague(具體同事類):它是抽象同事類的子類菩鲜;每一個同事對象在需要和其他同事對象通信時园细,先與中介者通信,通過中介者來間接完成與其他同事類的通信接校;在具體同事類中實現(xiàn)了在抽象同事類中聲明的抽象方法猛频。

4、中介者類承擔了兩方面的職責

1)中轉(zhuǎn)作用(結(jié)構(gòu)性):通過中介者提供的中轉(zhuǎn)作用蛛勉,各個同事對象就不再需要顯式引用其他同事伦乔,當需要和其他同事進行通信時,可通過中介者來實現(xiàn)間接調(diào)用董习。該中轉(zhuǎn)作用屬于中介者在結(jié)構(gòu)上的支持烈和。

2)協(xié)調(diào)作用(行為性):中介者可以更進一步的對同事之間的關(guān)系進行封裝,同事可以一致的和中介者進行交互皿淋,而不需要指明中介者需要具體怎么做招刹,中介者根據(jù)封裝在自身內(nèi)部的協(xié)調(diào)邏輯,對同事的請求進行進一步處理窝趣,將同事成員之間的關(guān)系行為進行分離和封裝疯暑。該協(xié)調(diào)作用屬于中介者在行為上的支持。

5哑舒、結(jié)構(gòu)圖
中介者模式

二妇拯、示例

? 中介者模式的核心在于中介者類的引入。

1)先創(chuàng)建一個Mediator類洗鸵,表示抽象中介者越锈;

2)然后創(chuàng)建ConcreteMediator類,繼承自Mediator類膘滨,表示具體中介者甘凭;

3)然后創(chuàng)建Colleague類,表示抽象同事類火邓;

4)最后創(chuàng)建三個類ZhangSan丹弱、LiSi和WangWu德撬,繼承自Colleague類,表示具體同事類躲胳;

具體代碼如下:

Mediator類:

@interface Mediator : NSObject
- (void)add:(Colleague *)colleague;
- (void)sendMessage:(NSString *)message colleague:(Colleague *)colleague;
@end

@interface Mediator ()
@property(nonatomic, strong) NSMutableArray<Colleague *> *colleagues;
@end
@implementation Mediator
- (instancetype)init
{
    self = [super init];
    if (self) {
        _colleagues = [NSMutableArray array];
    }
    return self;
}

- (void)add:(Colleague *)colleague {
    [self.colleagues addObject:colleague];
}

- (void)sendMessage:(NSString *)message colleague:(Colleague *)colleague {}
@end

ConcreteMediator類:

@interface ConcreteMediator : Mediator

@end

@implementation ConcreteMediator
- (void)sendMessage:(NSString *)message colleague:(Colleague *)colleague {
    Colleague *zhangSan = self.colleagues[0];
    Colleague *liSi = self.colleagues[1];
    Colleague *wangWu = self.colleagues[2];
    
    if (colleague == zhangSan) {
        [liSi getMessage:message]; // 通過中介者調(diào)用同事類的方法
        [wangWu getMessage:message];
    } else if (colleague == liSi) {
        [zhangSan getMessage:message];
    }
}
@end

Colleague類:

@interface Colleague : NSObject
@property(nonatomic, strong) Mediator *mediator; //維持一個抽象中介者的引用
- (instancetype)initWithMediator:(Mediator *)mediator;
- (void)sendMessage:(NSString *)message; //定義依賴方法蜓洪,與中介者進行通信
- (void)getMessage:(NSString *)message; //聲明自身方法,處理自己的行為
@end

@implementation Colleague
- (instancetype)initWithMediator:(Mediator *)mediator {
    self = [super init];
    if (self) {
        _mediator = mediator;
    }
    return self;
}

- (void)sendMessage:(NSString *)message {}
- (void)getMessage:(NSString *)message {}
@end

ZhangSan坯苹、LiSi和WangWu類:

// ZhangSan
@interface ZhangSan : Colleague
@end
@implementation ZhangSan
- (void)sendMessage:(NSString *)message {
    NSLog(@"張三發(fā)送消息:%@", message);
    [self.mediator sendMessage:message colleague:self];
}

- (void)getMessage:(NSString *)message {
    NSLog(@"張三接收消息:%@", message);
}
@end

// LiSi
@interface LiSi : Colleague
@end
@implementation LiSi
- (void)sendMessage:(NSString *)message {
    NSLog(@"李四發(fā)送消息:%@", message);
    [self.mediator sendMessage:message colleague:self];
}

- (void)getMessage:(NSString *)message {
    NSLog(@"李四接收消息:%@", message);
}
@end

// WangWu
@interface WangWu : Colleague
@end
@implementation WangWu
- (void)sendMessage:(NSString *)message {
    NSLog(@"王五發(fā)送消息:%@", message);
    [self.mediator sendMessage:message colleague:self];
}

- (void)getMessage:(NSString *)message {
    NSLog(@"王五接收消息:%@", message);
}
@end

運行代碼:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 創(chuàng)建中介者對象
    ConcreteMediator *mediator = [ConcreteMediator new];
    // 創(chuàng)建同事對象蝠咆,傳入同一個中介者
    Colleague *zhangSan = [[ZhangSan alloc] initWithMediator:mediator];
    Colleague *liSi = [[LiSi alloc] initWithMediator:mediator];
    Colleague *wangWu = [[WangWu alloc] initWithMediator:mediator];
    // 給中介者綁定三個對象
    [mediator add:zhangSan];
    [mediator add:liSi];
    [mediator add:wangWu];
    
    // 發(fā)送消息
    [zhangSan sendMessage:@"我愛你們"];
    NSLog(@"-----------------------");
    [liSi sendMessage:@"我不喜歡張三"];
}

打印結(jié)果:

張三發(fā)送消息:我愛你們
李四接收消息:我愛你們
王五接收消息:我愛你們
-----------------------
李四發(fā)送消息:我不喜歡張三
張三接收消息:我不喜歡張三

三、總結(jié)

? 中介者模式將一個網(wǎng)狀的系統(tǒng)結(jié)構(gòu)變成一個以中介者對象為中心的星形結(jié)構(gòu)北滥,在這個星型結(jié)構(gòu)中,使用中介者對象與其他對象的一對多關(guān)系來取代原有對象之間的多對多關(guān)系闸翅。

1再芋、優(yōu)點

1、簡化了對象之間的交互:它用中介者和同事的一對多交互代替了原來同事之間的多對多交互坚冀,一對多關(guān)系更容易理解济赎、維護和擴展,將原本難以理解的網(wǎng)狀結(jié)構(gòu)轉(zhuǎn)換成相對簡單的星型結(jié)構(gòu)记某。

2司训、可將各同事對象解耦:中介者有利于各同事之間的松耦合,我們可以獨立的改變和復(fù)用每一個同事和中介者液南,增加新的中介者和新的同事類都比較方便壳猜,更好地符合“開閉原則”。

3滑凉、減少子類生成:中介者將原本分布于多個對象間的行為集中在一起统扳,改變這些行為只需生成新的中介者子類即可,這使各個同事類可被重用畅姊,無須對同事類進行擴展咒钟。

2、缺點

? 在具體中介者類中包含了大量同事之間的交互細節(jié)若未,可能會導(dǎo)致具體中介者類非常復(fù)雜朱嘴,使得系統(tǒng)難以維護。

3粗合、適用場景

1萍嬉、系統(tǒng)中對象之間存在復(fù)雜的引用關(guān)系,系統(tǒng)結(jié)構(gòu)混亂且難以理解隙疚。

2帚湘、一個對象由于引用了其他很多對象并且直接和這些對象通信,導(dǎo)致難以復(fù)用該對象甚淡。

3大诸、想通過一個中間類來封裝多個類中的行為捅厂,而又不想生成太多的子類∽嗜幔可以通過引入中介者類來實現(xiàn)焙贷,在中介者中定義對象交互的公共行為,如果需要改變行為則可以增加新的具體中介者類贿堰。

4辙芍、iOS應(yīng)用舉例

? 在進行iOS組件化的時候,就是利用中介者模式處理組件之間的交互羹与。

Demo地址:iOS-Design-Patterns

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末故硅,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子纵搁,更是在濱河造成了極大的恐慌吃衅,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腾誉,死亡現(xiàn)場離奇詭異徘层,居然都是意外死亡,警方通過查閱死者的電腦和手機利职,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門趣效,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人猪贪,你說我怎么就攤上這事跷敬。” “怎么了热押?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵干花,是天一觀的道長。 經(jīng)常有香客問我楞黄,道長池凄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任鬼廓,我火速辦了婚禮肿仑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘碎税。我一直安慰自己尤慰,他們只是感情好,可當我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布雷蹂。 她就那樣靜靜地躺著伟端,像睡著了一般。 火紅的嫁衣襯著肌膚如雪匪煌。 梳的紋絲不亂的頭發(fā)上责蝠,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天党巾,我揣著相機與錄音,去河邊找鬼霜医。 笑死齿拂,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的肴敛。 我是一名探鬼主播署海,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼医男!你這毒婦竟也來了砸狞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤镀梭,失蹤者是張志新(化名)和其女友劉穎刀森,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丰辣,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年禽捆,在試婚紗的時候發(fā)現(xiàn)自己被綠了笙什。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡胚想,死狀恐怖琐凭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情浊服,我是刑警寧澤统屈,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站牙躺,受9級特大地震影響愁憔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜孽拷,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一吨掌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧脓恕,春花似錦膜宋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至乃秀,卻和暖如春肛著,著一層夾襖步出監(jiān)牢的瞬間圆兵,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工策泣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留衙傀,地道東北人。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓萨咕,卻偏偏與公主長得像统抬,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子危队,可洞房花燭夜當晚...
    茶點故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容