Mediator(中介者)模式在iOS開發(fā)當(dāng)中的使用

因?yàn)?a target="_blank" rel="nofollow">https://blog.csdn.net/urdfmqcul2/article/details/78788962
,博客搬家至https://juejin.im/user/59fd6315f265da4321536990

首先來看看wiki上對(duì)中介者模式的解釋:

In software engineering, the mediator pattern defines an object that encapsulates how a set of objects interact. This pattern is considered to be a behavioral pattern due to the way it can alter the program's running behavior.

在軟件工程中,中介模式定義了一個(gè)對(duì)象,該對(duì)象封裝了一組對(duì)象是如何交互的。這種模式被認(rèn)為是一個(gè)行為模式,因?yàn)樗梢愿淖兂绦虻倪\(yùn)行行為。

在一個(gè)項(xiàng)目里,我們開發(fā)的程序是由大量的類來組成的,隨著程序功能的不斷增加,類和類之間的依賴關(guān)系也跟著趨于復(fù)雜,而中介者模式便能解決這個(gè)問題。

這種復(fù)雜的依賴關(guān)系,在iOS開發(fā)當(dāng)中常用的MVC模式中定義的ViewController(VC)就是典型的代表。一般情況下一個(gè)頁面便對(duì)應(yīng)代碼中的一個(gè)VC,而一個(gè)中等規(guī)模的軟件至少會(huì)有幾十個(gè)的頁面,對(duì)應(yīng)的就是幾十個(gè)VC。(當(dāng)然你也可以說復(fù)用VC,但是在正常情況下,VC的復(fù)用場(chǎng)景會(huì)有這么多么?這里我們不考慮復(fù)用VC的情況。)而要管理這些VC之間的關(guān)系是一件非常繁瑣的事情,我們要處理各個(gè)VC之間的關(guān)系,每當(dāng)一個(gè)VC要跳轉(zhuǎn)到另外個(gè)VC,我們需要包含新的VC的頭文件,于是有的起銜接作用的頁面中包含了大量的其他VC的頭文件。同時(shí)每當(dāng)產(chǎn)品經(jīng)理要求修改一些頁面的邏輯關(guān)系,我們又需要對(duì)這些頭文件和對(duì)應(yīng)的代碼進(jìn)行修改,想想我就頭大。類似下圖:

而使用中介者模式可以非常好地去解決這個(gè)問題。實(shí)現(xiàn)一個(gè)管理VC關(guān)系的功能類,這個(gè)類的作用是給每個(gè)VC綁定一個(gè)URL,當(dāng)需要打開某一個(gè)新的VC時(shí),通過功能類的openURL接口傳入新VC的URL即可。發(fā)起openURL的一方不需要去依賴新的VC,只需要和功能類建立聯(lián)系,類似下圖:

Mediator類的作用就相當(dāng)于一個(gè)路由器(Router),將客戶發(fā)起的URL請(qǐng)求轉(zhuǎn)移到對(duì)應(yīng)的類。我們還可以利用iOS應(yīng)用本身的特點(diǎn),以及Objective-C語言的特性,給這個(gè)Router增加一些功能:
在一些特殊情況下,打開不同的頁面(VC)之后,還需要傳遞一些命令到這個(gè)VC,讓其做一些特殊的操作,于是可以通過配置URL的參數(shù),再通過參數(shù)名和參數(shù)值傳遞給新VC:

[MRRouter openURL:@"scheme://test?aa=11&bb=22"];

更方便的,可以直接用字典來傳遞參數(shù):

[MRRouter openURL:@"scheme://test3" parameters:@{@"ccc":@"333",@"ddd":@"444"}];

于是還需要?jiǎng)?chuàng)建一個(gè)映射表,來建立URL和VC之間的映射關(guān)系,每增加一個(gè)VC,就在這個(gè)表里頭增加一個(gè)對(duì)應(yīng)關(guān)系。這里可以利用Objective-C的Runtime來動(dòng)態(tài)地根據(jù)類名去映射,簡(jiǎn)化我們的日常編碼操作,具體的實(shí)現(xiàn)就不在這里詳細(xì)描述了,有興趣可以去這里看具體的實(shí)現(xiàn)。

還可以定義一個(gè)默認(rèn)的openURL操作:

[MRRouter sharedInstance].defaultExecutingBlock = ^(id object, NSDictionary *parameters) { 
    [self.navigationController pushViewController:object animated:YES];
};

這樣在一般情況下打開一個(gè)新的頁面,不需要引入任何頭文件,也不需要建立映射關(guān)系,只需要調(diào)用Router的openURL接口。

通過以中介者模式為基礎(chǔ)的Router管理頁面的額外好處,就是可以簡(jiǎn)化服務(wù)端push需要打開新頁面的操作,當(dāng)有一個(gè)新的活動(dòng),要打開一個(gè)對(duì)應(yīng)的頁面,只需要把這個(gè)頁面的URL通過push發(fā)送給客戶端,客戶端直接傳遞給Router即可,省略了大量的if/else的邏輯判斷。

總結(jié):

中介者模式的使用不光用在VC的管理,當(dāng)功能中出現(xiàn)了類似“多對(duì)多”的復(fù)雜的對(duì)象群時(shí),就可以用到它來管理這些對(duì)象。當(dāng)然,再次之前,你需要考慮的不應(yīng)該是開始使用中介者模式,而是考慮這個(gè)功能的設(shè)計(jì)是否合理。
使用中介者模式雖然降低了各個(gè)對(duì)象之間的耦合,減少了對(duì)象之間邏輯的復(fù)雜度,但是這個(gè)復(fù)雜度在一定程度上轉(zhuǎn)移到了Mediator類中,因此Mediator類的功能維護(hù)需要謹(jǐn)慎處理。
以上舉例中的所有代碼可以在這里下載,歡迎各種star/request/issue。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容