模塊化的方案總結

一、為什麼要組件化

1.實現之間解耦、減少項目的編譯時間,提升業務開發效率。

通常一個工程中會有多個模塊,而模塊之間會有依賴關係,比如A調用B,那麼在A模塊中就會引用B模塊的頭文件,同時可能B模塊又會依賴C模塊,C模塊又會依賴A模塊等等,最終的結果是各模塊高度耦合,特別是大型的工程,耦合特別嚴重。如下圖所示

iOS組件化/模塊化的方案總結

如果想避免耦合,那麼我們需要設計一種結構避免,各模塊之間耦合,可以如下圖所示結構:

iOS組件化/模塊化的方案總結


這種結構有什麼好處呢?
1)首先是將模塊拆分成組件單獨管理,拆分成單獨的庫,這樣各組件在進行開發的時候,只需要編譯自己的庫文件,大大減少文件的編譯時間,我們的工程,之前編譯需要20分鐘左右,現在只需幾分鐘,這個對效率提高,非常明顯。
2)各個庫單端管理,可以進行權限設置,只有各組件相關人員才可以修改組件代碼,不會出現一個大的工程中,A修改了B的代碼的情況,可以一定程度上保證代碼的安全性。


2.合併項目容易出現衝突。

在每次發版以後,release分支會向dev分支合併代碼,由於各組件會提交許多代碼,不同的開發者可能會同時修改同一個文件,引起衝突,這樣一個工程中就會出現多處的合併衝突,比如一個幾十人的團隊,這個衝突的概率非常大,需要各組件的人去dev分支修改自己組件的衝突,如果衝突沒有解決,整個工程都無法運行,影響整個團隊的開發,非常影響效率。

3.模塊拆分成組件,方便對外付能

假設一個項目中有多個組件,相互耦合,這個時候想單獨將一個組件拆分出來,提供給它人使用,幾乎是不可能的,而組件化接觸這種耦合之後,我們可以直接將某個組件單獨提供給它人使用,各個組件可以像積木一樣,相互組合起來,形成一個新的APP對外付能。

二、組件化方案

組件化方案,主要分為兩個部分,一是代碼如何解耦,二是如何進行版本管理,下面分別進行詳細講解。

1.代碼解耦

1)組件原則
組件通常分為兩種類型的組件:基礎組件,業務組件。
*業務組件依賴基礎組件
*基礎組件不可依賴業務組件。
*業務組件間不可相互依賴。

2)組件間的通信方式:
組件間通信方式,業內主要有兩種實現方式:
1.協議式框架,比如蘑菇街的這種方案。蘑菇街 App 的組件化之路


2. 中間者架構,比如casatwy的方案。casatwy關於蘑菇街組件化的討論

我們來總結一下目前的方案
蘑菇街方案-基於URL和協議
1)通過URL傳遞簡單參數(組件間簡單參數調用)
2)通過協議調用傳遞複雜參數(組件間複雜參數調用)


缺點:
1)頁面間調用不需要URL形式,對於複雜參數,組件間調用通過URL無法滿足需求。
2)註冊URL時充分不必要條件,完全可以用runtime來解決這個問題。
3)使用多種方案,不利於管理和維護。
4)protocol主要存在的問題就是分散調用導致耦合。
5)需要組件向ModuleManager註冊Url(因為URL調用時通過註冊時的callBack來實現的,不是基於runtime,所以需要註冊),會導致浪費內存。

casatwy的方案-基於Category和Target-Action


主要是基於Mediator模式和Target-Action模式,中間採用了runtime來完成調用。通過mediator的Category來輸出組件的對外調用方法。使用同一種方案,實現組件間調用。


優點:
1)不需要註冊URL
2)使用同一種方案,基於Target-Action模式實現組件間的調用。
3)區分app內部調用和外部調用。
4)同一種方法可以實現簡單參數和複雜參數的調用。

我們的方案-基於URL和Target-Action


利用runtime實現Target-Action模式設計,通過定義URL協議確定Target和Action,通過params來傳遞所有頁面間調用的參數,error返回調用的錯誤信息,completion來實現調用後的回調。類似以下形式
組件調用方式:[XXMediator openURL:@"mediator://Target/Action" arg:params error:error completion:callBack]
組件輸出調用方法:每個組件有一個XXModule的類,在該類中實現對外輸出的方法,提供XXMediator中Target和Action。類的頭文件中包含組件可以調用的類以及需要傳遞的參數。

優點:
1)一種調用方式,可以實現簡單和複雜參數調用。
2)不需要註冊,調用簡單
3)所有調用使用同一個方法實現,只需要引用Mediator,不需要引用Mediator 的category。
4)通過URL實現Target-Action,可以利用URL規則解析出Target和Action,實現調用。

2.版本管理

版本管理使用 cocoapods,每個組件都拆成獨立的pod庫,並生成一個配置表,來進行組件間的依賴組件的版本管理,具體內容這裡就不敘述了。

三、組件化遇到問題

1.使用Target-Action方式進行調用,有個問題就是runtime的時候,如果對應Target-Action修改了,怎麼提示調用方


1)靜態檢測URL,判斷Target-Action是否存在。
2)動態調用router,debug模式下,Target-Action不存在就crash。

2.調用方如何知道接收方需要哪些key的參數?調用方如何知道有哪些target可以被調用?
1)category方式下,可以直接通過category中的方法來進行確認。
2)我們的方案中,每個組件的對應moudle類中,類的頭文件中包含組件可以調用的類以及需要傳遞的參數。


3.調用參數解析處理在

那裡比較好?

各組件內部,因為這些參數的使用,各組件開發者自己最清楚。如果在category解析,Mediator中會參雜業務邏輯。

4.A調用B時,如果B要回傳參數給,怎麼做?

通過callBackBlock回調回傳,參數是id類型,可以傳任意對象,比如是一個UIViewController或者一個NSDictionary都可以。

四.組件化的缺點:

1.會增加開發者的學習成本
2.組件拆分顆粒度把握不好,會產生很多中間代碼和冗餘。
3.圖片資源管理不好,會產生很多冗餘圖片。
4.組件化過程中,會帶來一些組件之間的調試問題,前期會影響團隊效率。

總結:

組件化是一把雙刃劍,如果在工程規模較小的時候,進行組件化,可能反而會影響團隊開發效率,帶來一些問題,比如上面提到的缺點,只是在工程和團隊達到一定規模的時候,進行組件化才會有更大的收益。


分享到:


相關文章: