模塊化與解耦(blog)

模塊化與解耦

簡述

本文主要講述了在iOS開發(fā)過程中,模塊化工程架構(gòu)的一種組織方式句各,本文主要講述基于cocoapods來做模塊化的方案吸占,詳細講述了iOS開發(fā)怎么進行模塊劃分的內(nèi)容,主要會在以下方面做闡述:

為什么要做模塊化

模塊設(shè)計原則

模塊化開發(fā)有哪些優(yōu)點和缺點

解耦與通信

1.為什么要做模塊化诫钓?

我們都知道最基本的代碼設(shè)計原則:“Don’t repeat yourself!”旬昭,每一個工程都會有自己的架構(gòu)篙螟,即使你是剛?cè)腴T的開發(fā)者菌湃,寫幾天代碼也會發(fā)現(xiàn)要把一些常用到的重復(fù)代碼單獨拿出來放在一個叫common的地方,實現(xiàn)代碼復(fù)用遍略。這樣看來每個開發(fā)者其實都或多或少的做過架構(gòu)方面的事情惧所,每個團隊至少有1~2個人在做這樣的事情骤坐。

說道app代碼架構(gòu),記得Samurai的開發(fā)者郭虹宇在群里說過這段精辟的話下愈,引用一下:

一派是說app開發(fā)并不需要什么狗P架構(gòu)纽绍,第二派說我們有自己NB的架構(gòu),第三派說只要模塊化夠好势似,每個模塊應(yīng)該有自己的架構(gòu)拌夏。

這三個觀點的出發(fā)點,我覺得也比較好理解履因,第一種應(yīng)該是一些個人開發(fā)者障簿,個人能力很強,經(jīng)常一個人很快搞出來一個app栅迄,他的映像中不需要弄太多的框框框住自己站故,但是其實他也是有一套自己的架構(gòu)的。第二派應(yīng)該是一些公司或者大公司毅舆,有一套NB的架構(gòu)對于團隊的意義就比較大了西篓,可以保證穩(wěn)定迭代,保證規(guī)范和持久可維護性憋活。第三派應(yīng)該是BAT這樣的有很多BU的超級公司岂津,或者一些先進的開源開發(fā)者們,模塊化能夠更好的實現(xiàn)跨app的代碼和功能的復(fù)用, 能夠更好的共享資源悦即,避免重復(fù)造輪子寸爆。

那么為什么要做模塊化?已經(jīng)很明顯了盐欺,模塊化的代碼框架最屌赁豆,不信,看看蘋果的框架怎么做的冗美,你就明白了魔种。

2. 模塊設(shè)計原則

既然模塊化最屌,那怎么才能做好project的模塊化拆分呢粉洼,哪些代碼應(yīng)該被放到一個模塊节预?這里分享一些我的經(jīng)驗。

越底層的模塊属韧,應(yīng)該越穩(wěn)定安拟,越抽象,越具有高復(fù)用度宵喂。

這一點糠赦,目測大家應(yīng)該比較認同,越是底層的SDK,就應(yīng)該越穩(wěn)定拙泽,穩(wěn)定的最直觀表現(xiàn)就是API很久都不用變化淌山,所有的變化因子不要暴露出來,避免傳遞給依賴它的模塊顾瞻。但是要做到設(shè)計一套API很久都不用改變泼疑,那么就需要設(shè)計的時候能越抽象, 即需要我們抽象總結(jié)的能力。

穩(wěn)定性還有一個特點就是會傳遞荷荤,比如 B 模塊依賴了 A 模塊退渗,如果 B 模塊很穩(wěn)定,但是 A 模塊不穩(wěn)定蕴纳,那么B模塊也會變的不穩(wěn)定了氓辣,因此下一個原則:

不要讓穩(wěn)定的模塊依賴不穩(wěn)定的模塊, 減少依賴

既然上面說最好不要依賴袱蚓,但是我發(fā)現(xiàn)我的 B 模塊的確依賴了 A 模塊里面不可或缺的代碼怎么辦钞啸? 假設(shè)依賴的代碼段為 x , 現(xiàn)在來看x的特性, 如果X是一個可能高復(fù)用的代碼段,那么無妨把x從 A 模塊里面拿出來喇潘,單做成一個模塊 X, 那么 B 模塊依賴 X 模塊就好了体斩;靈一種情況,x是一個方法或函數(shù)颖低,而且不太適合單做成一個模塊絮吵,所以那就在B模塊里面拷貝一份 x 代碼就ok了,因為這樣可以保證模塊的穩(wěn)定性自完備性.

如果上面兩種方法都不太合適忱屑,我們會在后面解耦里面講到如何解耦

提升模塊的復(fù)用度蹬敲,自完備性有時候要優(yōu)于代碼復(fù)用

什么是自完備性,就是盡可能的依賴少的模塊來達到代碼可復(fù)用莺戒。

舉個例子伴嗡,我有個模塊Utils里面放了大量的category工具方法等,在日常UI產(chǎn)品開發(fā)中从铲,依賴這個Utils會很方便瘪校,但是我現(xiàn)在要寫一個比較基礎(chǔ)的模塊,應(yīng)該就要求復(fù)用度更高一些名段,這個時候需要用到Utils里面的幾個方法阱扬,那這個時候還適合直接依賴Utils嗎,當(dāng)然不合適了伸辟,這與我們上面的設(shè)計原則相悖了啊麻惶,因此我們這時候為了這個模塊的自完備性,就可以重新實現(xiàn)下這幾個方法信夫,而不是依賴Utils模塊

每個模塊只做好一件事情窃蹋,不要讓Common出現(xiàn)

模塊化結(jié)構(gòu)是讓工程結(jié)構(gòu)更清晰卡啰,每個模塊都只做一件事情,都有自己的一個命名脐彩,這樣這個模塊才能良性發(fā)展碎乃, 但是這個名字千萬不要再叫Common了姊扔,試想下你有沒有做過這樣的事情:“哎呀惠奸,這塊代碼放哪都不太合適,放Common吧”恰梢, 日久以后佛南,這個Common就變成了毒瘤,大家都依賴它嵌言,還一堆不相關(guān)的代碼嗅回,這個Common模塊就是我們設(shè)計原則第一點的反面教材: “非常不穩(wěn)定,大量依賴摧茴,全是耦合绵载,整個模塊無法復(fù)用到其他app”, 所以刪掉工程里面的Common吧,再遇到不知道放哪的代碼苛白,就要好好思考模塊的設(shè)計娃豹,再不行如果具有可復(fù)用性就單建一個模塊吧,為什么不可以呢购裙?

按照你架構(gòu)的層數(shù)從上到下依賴懂版,不要出現(xiàn)下層模塊依賴上層模塊的現(xiàn)象

業(yè)務(wù)模塊之間也盡量不要耦合

3. 模塊化開發(fā)有哪些優(yōu)點和缺點

優(yōu)點: 1、不只提高了代碼的復(fù)用度躏率,還可以實現(xiàn)真正的功能復(fù)用躯畴,比如同樣的功能模塊如果實現(xiàn)了自完備性,可以在多個app中復(fù)用 2薇芝、業(yè)務(wù)隔離蓬抄,跨團隊開發(fā)代碼控制和版本風(fēng)險控制的實現(xiàn) 3、模塊化對代碼的封裝性夯到、合理性都有一定的要求倡鲸,提升開發(fā)同學(xué)的設(shè)計能力。

缺點,模塊化當(dāng)然也有它的缺點: 1黄娘、入門門檻較高峭状,新手入門需要的成本也更高 2、工具的使用成本逼争,團隊間和模塊間的配合成本升高优床,開發(fā)效率短期會降低。

但是從長期的影響來說誓焦,帶來的好處遠大于壞處的胆敞,因此模塊化仍然是最佳的架構(gòu)選擇着帽。

4. 解耦與通信

我先說說為什么要解耦吧,模塊化并不是說你把工程的代碼拆分成 50 個 pod 或者framework就算完事了移层,要實現(xiàn)模塊之間真正的解耦才算真正的模塊化仍翰,否則如果模塊之間還都是互相調(diào)用代碼,循環(huán)依賴观话,那么和原本放文件夾里面沒啥兩樣予借。那么什么是模塊間的解耦呢?

模塊解耦的目標就是, 在基于模塊設(shè)計原則上, 讓模塊之間沒有循環(huán)依賴, 讓業(yè)務(wù)模塊之間解除依賴频蛔。

4.1 公共模塊下沉

這塊其實還是講的模塊設(shè)計灵迫,一個工程的架構(gòu)可能會分為很多層,然而在開發(fā)的過程中晦溪,很容易有人不注意讓應(yīng)該處于較底層的模塊依賴了上層的模塊瀑粥,這種情況下應(yīng)該對模塊的設(shè)計進行改造實現(xiàn)單向依賴。

比如一個常見的普遍的例子: 一個公共的WebView模塊三圆,里面可能有WebViewController的基類狞换,然后還有JSBridge的服務(wù),如果設(shè)計的時候沒有注意舟肉,很容易在開發(fā)過程中修噪,這個模塊被塞入大量的其他業(yè)務(wù)代碼,依賴了一大堆業(yè)務(wù)模塊度气,因為經(jīng)常注冊JSBridge服務(wù)需要跟業(yè)務(wù)耦合割按。

這個時候怎么做呢,首先我們要思考WebView模塊的定位磷籍,從更全局的角度思考适荣,每個app的架構(gòu)應(yīng)該都需要這樣一個模塊,那么我們完全可以把這個模塊單獨拎出來下沉為基礎(chǔ)模塊院领,這個時候的解耦就需要你對WebView模塊做出一些設(shè)計弛矛,添加一些注冊型Api,修改JSBridge的服務(wù)為可以通過注冊的方式添加邏輯比然,這樣來實現(xiàn)與業(yè)務(wù)解耦丈氓,業(yè)務(wù)完全可以把與自己業(yè)務(wù)相關(guān)的代碼放在自己的模塊里面,然后通過你設(shè)計的Api注冊到WebView模塊中强法。

4.2 面向接口調(diào)用

雖然說公共模塊可以通過架構(gòu)設(shè)計來避免耦合業(yè)務(wù)万俗,但是業(yè)務(wù)模塊之間還是會有耦合的啊,而且這種情況是最多的饮怯,比如頁面跳轉(zhuǎn)啊闰歪,數(shù)據(jù)傳遞啊,這些情況前面的方法已經(jīng)不夠用了蓖墅。那如何解耦不同業(yè)務(wù)模塊之間的代碼調(diào)用呢库倘?

那就是面向接口調(diào)用临扮,我們知道只要直接引用代碼,就會有依賴教翩,比如:

123456789

// A 模塊-(void)getSomeDataFromB{B.getSomeData();}// B 模塊-(void)getSomeData{returnself.data;}

那么我們可以實現(xiàn)一個getSomeDataFromB的接口杆勇,讓 A 只依賴這個接口,而 B 來實現(xiàn)這個接口饱亿,這樣就實現(xiàn)了 A 與 B 的解耦。

12345678910111213141516171819

// 接口@protocolBService-(void)getSomeData;@end// A 模塊, 只依賴接口-(void)getSomeDataFromB{idb=findService(@protocol(BService));b.getSomeData;}// B 模塊传黄,實現(xiàn)BService接口@interfaceB:NSObject-(void)getSomeData{returnself.data;}@end

這樣就可以實現(xiàn)了即滿足了模塊之間調(diào)用,也實現(xiàn)了解耦

優(yōu)點:

1膘掰、接口類似代碼识埋,可以非常靈活的定義函數(shù)和回調(diào)等系忙。

缺點:

1、接口定義文件需要放在一個模塊以供依賴蛹疯,但是這個模塊不回貢獻代碼,所以還好列吼。

2、使用較為麻煩凑耻,每各調(diào)用都需要定義一個service类缤,并實現(xiàn), 對于一些具有普適性規(guī)律的場景不太合適,比如頁面統(tǒng)一跳轉(zhuǎn)

4.3 面向協(xié)議調(diào)用

面向接口調(diào)用的缺點導(dǎo)致并不能滿足所有的需求,也解耦的不夠徹底驮瞧,那么終極手段就是通過定義一套協(xié)議來實現(xiàn)模塊間的通信,協(xié)議現(xiàn)成的狂魔,那就是URL跳轉(zhuǎn)協(xié)議待错,基本滿足需要蚯撩,簡單易上手,基本上現(xiàn)在很多的App架構(gòu)里面都會有“統(tǒng)一跳轉(zhuǎn)” 這一套東西的,這個不光是對模塊解耦有幫助,對于統(tǒng)一化運營都是有極好的幫助的称杨,比如app里面的任何頁面,或者任何操作都是通過一個URL來喚起的話,這樣是不是就把各個復(fù)雜的業(yè)務(wù)之間解耦了呢般婆,通信都使用URL.

5. 源碼推薦

說了這么多廉侧,也要放點干貨吧栈拖,下面給出2個庫的介紹涩哟,對你模塊化的進程希望有幫助索赏。

1、JLRoutes是一個URL跳轉(zhuǎn)協(xié)議支持的庫,跟我想要的簡直很契合器仗,強烈推薦威鹿。

2根蟹、 我自己寫的一個解耦框架AppLord. 簡單介紹一下幾個概念

* Module 是負責(zé)管理啟動模塊的工具买决,可以幫助你把AppDelegate里面一坨初始化的代碼分別放到不同的module里面去

* Service 就是對上面 4.2 中面向接口解耦方式的一種封裝

* Task, 全局的后臺任務(wù)管理器,有時候一些不知道放哪的任務(wù)執(zhí)行可以塞進去

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吼畏,一起剝皮案震驚了整個濱河市躲舌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌性雄,老刑警劉巖没卸,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異秒旋,居然都是意外死亡约计,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門迁筛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來煤蚌,“玉大人,你說我怎么就攤上這事细卧∥咀” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵贪庙,是天一觀的道長蜘犁。 經(jīng)常有香客問我,道長止邮,這世上最難降的妖魔是什么这橙? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮农尖,結(jié)果婚禮上析恋,老公的妹妹穿的比我還像新娘。我一直安慰自己盛卡,他們只是感情好助隧,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般并村。 火紅的嫁衣襯著肌膚如雪巍实。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天哩牍,我揣著相機與錄音棚潦,去河邊找鬼。 笑死膝昆,一個胖子當(dāng)著我的面吹牛丸边,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播荚孵,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼妹窖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了收叶?” 一聲冷哼從身側(cè)響起骄呼,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎判没,沒想到半個月后蜓萄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡澄峰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年嫉沽,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摊阀。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡耻蛇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出胞此,到底是詐尸還是另有隱情,我是刑警寧澤跃捣,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布漱牵,位于F島的核電站,受9級特大地震影響疚漆,放射性物質(zhì)發(fā)生泄漏酣胀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一娶聘、第九天 我趴在偏房一處隱蔽的房頂上張望闻镶。 院中可真熱鬧,春花似錦丸升、人聲如沸铆农。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽墩剖。三九已至猴凹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間岭皂,已是汗流浹背舱沧。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工创倔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓趣斤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親酒来。 傳聞我的和親對象是個殘疾皇子蚂维,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,116評論 25 707
  • ** 注意:本文并非原創(chuàng)文章,轉(zhuǎn)載自(原創(chuàng)):https://blog.cnbluebox.com/blog/20...
    VV木公子閱讀 5,983評論 9 36
  • 小白讓我叫他哥哥毙籽,呵呵洞斯,我要是叫哥哥了估計就真的是哥哥了。所以我固執(zhí)的叫他小白坑赡,他反抗過N次說小白聽起來像一只狗的...
    標有梅閱讀 235評論 0 0
  • 版權(quán)聲明本文首發(fā)自微信公眾帳號:runner2sun烙如;無需授權(quán)即可轉(zhuǎn)載,但請自覺保留以上版權(quán)聲明毅否。 《把時間當(dāng)作朋...
    逐日的我閱讀 355評論 0 0
  • 也許亚铁,觀音山應(yīng)該算不上是一部好看的電影。 幾年前就看過李玉的電影《紅顏》螟加,講述在四川某個小城鎮(zhèn)徘溢,一位女人坎坷并且戲...
    mouxing閱讀 803評論 2 10