iOS 移動(dòng)端組件化

路由是一個(gè)很好的解耦的方案寸宵,它可以為各個(gè)組件之間調(diào)用提供遍歷,沒有路由,組件化也是可以用的赡译。

業(yè)界常見的三種解決方案

1.Url-scheme注冊(cè)(MGJRouter)

iOS系統(tǒng)中默認(rèn)是支持 url scheme方式的,例如可以在瀏覽器中輸入: weixin:// 就可以打開微信應(yīng)用畸悬。自然在APP內(nèi)部也可以通過這種方法來實(shí)現(xiàn)組件之間的路由設(shè)計(jì)。

這種方式實(shí)現(xiàn)的原理是在APP啟動(dòng)的時(shí)候委煤,或者是向以下實(shí)例中的每個(gè)模塊自己的load方法里面注冊(cè)自己的斷鏈(url),以及對(duì)外提供服務(wù)(Block),通過url-scheme標(biāo)記好修档,然后維護(hù)在url-router里面碧绞。 url-router中保存了各個(gè)組件對(duì)應(yīng)的url-scheme,只要其它組件調(diào)用了 open url 的方法,url-router就會(huì)去根據(jù)url去查找對(duì)應(yīng)的服務(wù)并執(zhí)行吱窝,詳見demo讥邻。

1.1 URL的命名規(guī)范

遵循網(wǎng)上通用的 URIweb service模式的資源通用表示方式) 的格式,例如 appscheme://pathctd://home/scan

1.2 常見案例

1.2.1 JLRoutes git 上 star 最多的一個(gè)開源庫

本質(zhì)可以理解為保存一個(gè)全局的map院峡,keyurl,value是對(duì)應(yīng)存放的block數(shù)組计维,urlblock都會(huì)常駐在內(nèi)存中,當(dāng)打開一個(gè)url時(shí)撕予,GLRoutes就可以遍歷這個(gè)全局的map,通過url來執(zhí)行對(duì)應(yīng)的block蜈首。

1.2.2 routable-ios
1.2.3 HHRouter
1.2.4 MGJRouter

蘑菇街的技術(shù)團(tuán)隊(duì)開源的一個(gè)router实抡,特點(diǎn)是使用簡(jiǎn)單方便,JLRoutes的問題主要在于查找url的實(shí)現(xiàn)不夠高效欢策,通過遍歷而不是匹配吆寨。還有就是功能偏多。HHRouterurl查找是基于匹配踩寇,所以會(huì)更高效啄清,MGJRouter也是采用的這種方法,但它和viewcontroller綁定地過于緊密俺孙,一定程度上降低了靈活性辣卒。于是就有了 MGJrouter, 從數(shù)據(jù)結(jié)構(gòu)上看它和 HHRouter是一樣的掷贾。

蘑菇街方案不好的地方:

  1. URL注冊(cè)對(duì)于實(shí)施組件化是完全沒有必要的,拓展性和可維護(hù)性都降低荣茫;
  2. 基于 Open-url 的方案的話想帅,有一個(gè)致命缺陷:非常規(guī)對(duì)象無法參與本地組件間調(diào)度;但是可以通過傳遞parms來解決啡莉,但是這個(gè)區(qū)分了遠(yuǎn)程調(diào)用和本地調(diào)用的接口港准;
  3. 模塊內(nèi)部是否仍然需要使用URL去完成調(diào)度?是沒有必要的咧欣,為啥要復(fù)雜化浅缸?
  4. 當(dāng)組件多起來的時(shí)候,需要提供一個(gè)關(guān)乎URL和服務(wù)的對(duì)應(yīng)表魄咕,并且需要開發(fā)人員對(duì)這樣一個(gè)表進(jìn)行維護(hù);
  5. 這種方式需要在APP啟動(dòng)時(shí)衩椒,每個(gè)組件需要到路由管理中心注冊(cè)自己的URL及服務(wù),因此 內(nèi)存中需要保存這樣一份表蚕礼,當(dāng)組件多起來以后就會(huì)出現(xiàn)一些內(nèi)存的問題
  6. 混淆了本地調(diào)用和遠(yuǎn)程調(diào)用烟具,它們的處理邏輯是不同的,正確的做法應(yīng)該是把遠(yuǎn)程調(diào)用通過一個(gè)中間層轉(zhuǎn)化成本地調(diào)用奠蹬,如果把兩者混為一談朝聋,后期可能會(huì)出現(xiàn)無法區(qū)分業(yè)務(wù)的情況。比如對(duì)于組件無法響應(yīng)的問題囤躁,遠(yuǎn)程調(diào)用可能直接顯示一個(gè)404頁面冀痕,但是本地調(diào)用可能需要做其它處理。如果不加以區(qū)分狸演,那么就無法完成這種業(yè)務(wù)要求言蛇。 遠(yuǎn)程調(diào)用只能傳遞被序列化JSON的數(shù)據(jù),像UIImage這樣非常規(guī)的對(duì)象是不行的宵距,所以如果組件接口要考慮遠(yuǎn)程調(diào)用腊尚,這里的參數(shù)與就不能是這類非常規(guī)對(duì)象

2.利用Runtime實(shí)現(xiàn)的target-action方式(CTMediator)- 推薦

相較于url-scheme的方式進(jìn)行組件間的路由,runtime的方式借助了OC運(yùn)行時(shí)的特征满哪,實(shí)現(xiàn)了組件間服務(wù)的自動(dòng)發(fā)現(xiàn)婿斥,無需注冊(cè)即可實(shí)現(xiàn)組件間的調(diào)用,因此哨鸭,不管從維護(hù)性民宿、可讀性、擴(kuò)展性來說像鸡,都是一個(gè)比較完美的方案活鹰, 詳見demo。

原理:

傳統(tǒng)的中介者模式,這個(gè)中間件Mediator會(huì)依賴其它組件志群,其它組件也會(huì)依賴mediator, 但是能不能讓mediator不在依賴組件着绷,各個(gè)組件之間不再依賴,組件間調(diào)用只依賴中間者mediator赖舟?
casa 大神是這樣優(yōu)化的:
利用target-action的方式蓬戚,創(chuàng)建一個(gè)taget的類,里面定義了一些action方法宾抓,這些方法的結(jié)果是返回一個(gè)controller或其它object子漩,再給中間件CTMedator添加一個(gè)分類方法,定義組件外部可調(diào)用的方法接口,內(nèi)部實(shí)現(xiàn)方法 perform:target:action的方法石洗,主要通過runtime中的 NSClassFromString 獲取target類和 NSSelectorFromString 獲取方法名幢泼,這樣就可以執(zhí)行先去創(chuàng)建的 target類中的方法得到返回值,再通過分類中的方法傳值出去讲衫,完美解決~

3.protcol-class注冊(cè)

通過協(xié)議綁定缕棵,核心思想和代理傳值是一樣的,遵循協(xié)議涉兽,實(shí)現(xiàn)協(xié)議中的方法招驴,詳見demo。

主要思路
1枷畏、創(chuàng)建一個(gè)頭文件 CommonProtocol.h 别厘,里面存放各個(gè)模塊提供的協(xié)議。在各個(gè)模塊依賴這個(gè)頭文件拥诡,實(shí)現(xiàn)協(xié)議的方法触趴。
2、創(chuàng)建一個(gè)中間類 ProtocolMediator, 提供模塊的注冊(cè)和獲取模塊的功能(其實(shí)就是將類和協(xié)議名進(jìn)行綁定渴肉,放在一個(gè)字典里冗懦,key是協(xié)議名字符串,value是類)仇祭。
3披蕉、在各個(gè)模塊中實(shí)現(xiàn)協(xié)議,核心代碼如下:

Class cls = [[ProtocolMediator sharedInstance] classForProtocol:@protocol(B_VC_Protocol)];   
UIViewController<B_VC_Protocol> *B_VC = [[cls alloc] init];
[B_VC action_B:@"param1" para2:222 para3:333 para4:444];
[self presentViewController:B_VC animated:YES completion:nil];

總結(jié)
通過這次對(duì)路由方案的研究,認(rèn)識(shí)到了自己對(duì)系統(tǒng)架構(gòu)方面的認(rèn)識(shí)還是太少乌奇,以前并沒有認(rèn)真考慮怎么去設(shè)計(jì)一個(gè)好代碼嚣艇,我們需要的事寫一些優(yōu)質(zhì)代碼,牢記 低耦合华弓、高內(nèi)聚、職責(zé)單一邏輯清晰困乒,不能甘心做碼農(nóng)寂屏,只知道堆代碼!!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末迁霎,一起剝皮案震驚了整個(gè)濱河市吱抚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌考廉,老刑警劉巖秘豹,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異昌粤,居然都是意外死亡既绕,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門涮坐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凄贩,“玉大人,你說我怎么就攤上這事袱讹∑T” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵捷雕,是天一觀的道長(zhǎng)椒丧。 經(jīng)常有香客問我,道長(zhǎng)救巷,這世上最難降的妖魔是什么壶熏? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮征绸,結(jié)果婚禮上久橙,老公的妹妹穿的比我還像新娘。我一直安慰自己管怠,他們只是感情好淆衷,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著渤弛,像睡著了一般祝拯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上她肯,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天佳头,我揣著相機(jī)與錄音,去河邊找鬼晴氨。 笑死康嘉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的籽前。 我是一名探鬼主播亭珍,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼敷钾,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了肄梨?” 一聲冷哼從身側(cè)響起阻荒,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎众羡,沒想到半個(gè)月后侨赡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粱侣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年羊壹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甜害。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡舶掖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出尔店,到底是詐尸還是另有隱情眨攘,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布嚣州,位于F島的核電站鲫售,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏该肴。R本人自食惡果不足惜情竹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望匀哄。 院中可真熱鬧秦效,春花似錦、人聲如沸涎嚼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽法梯。三九已至苔货,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間立哑,已是汗流浹背夜惭。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铛绰,地道東北人诈茧。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像捂掰,于是被迫代替她去往敵國(guó)和親若皱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子镊叁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

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