三国杀武将|手游三国杀边锋版

iOS組件化開發架構設計思考(初版)

米米狗 2019-05-24 10:40:12 1784
本文來自 擇勢勤 ,作者 米米狗

組件化開發系列:

(一)iOS組件化開發架構設計思考

(二)iOS組件化開發實施一期文檔

一. 項目現狀

當前iOS端APP項目大概有35萬行代碼,早期為了iPad和iPhone雙端開發的效率,將所有業務模塊的網絡請求和數據模型統一抽離到DDEngine工程,自定義了私有開發庫DDDevLib工程,和第三方SDKs管理庫ThirdSDKs工程,和功能相對獨立的DDMIX_UI工程。在項目較小時,這個架構是完全可以滿足開發需要的,也是容易推進的。但是開發過程中缺少組件化的考量,隨著產品線的擴展和人員流動,對項目不熟悉和開發規范不夠嚴謹,造成業務模塊依賴關系非常復雜,主要有三類耦合:

工程耦合:某些模塊在運行時需要依賴主工程的代碼才能運行或實現完整的功能;

界面耦合:App 執行過程中,硬編碼的界面跳轉行為;

依賴耦合:兩個業務模塊之間的代碼依賴。

現在一處改動有可能造成多處受影響,需要測試同事做大量回歸測試,存在重復造輪子、項目編譯時間長、開發效率降低等問題。目前還只是基于OC編碼,Swift編碼也是項目演進的一個重要方向,Swift和OC的相互調用還不是很方便,暗坑無數,需要先對項目進行組件化演進,以便項目向Swift和OC混編過渡。

二. 方案調研

參考業內的流行方案

1、基于 URL Router、ModuleMediator

代表:蘑菇街 Limboy

image.png

URL組件化架構圖

優缺點:

1、URL Router方案,在使用時需要注冊模塊類,需要維護一個URL路由表,而且路由表一般保存服務端,拓展性和可維護性降低。

2、非常規對象無法直接參與本地組件間調度,模塊之間用URL去完成調度,徒增復雜化。

3、項目中已有URL路由配置,URL Router 開發起來相對比較容易推進。

2、基于 Target-Action、Runtime、Category

代表:安居客 Casa Taloyum

image.png

Target-Action組件化架構圖

優缺點:

1、將遠程調用和本地調用做了拆分,而且由本地應用調用位遠程應用調用提供服務,安全保證,對url中進行native前綴驗證。

2、模塊僅通過Action暴露可調用接口,必需去Model設計:只有調用方依賴Mediator,響應方依賴是沒有必要的。

3、模塊調用存在一定的硬編碼問題,可以通過在模塊中維護針對DDMediator的Category,每個category對應一個target,categroy中的方法對應Action場景。

4、業務發現的模式,存在業務調用的未知性,代碼的可讀性有所降低。

主要是基于Mediator模式和Target-Action模式,中間采用了runtime來完成調用。這套組件化方案將遠程應用調用和本地應用調用做了拆分,而且是由本地應用調用為遠程應用調用提供服務。

3、去model化

在組件和模塊拆分之前,一定要明確一個概念,組件間調用是需要針對參數做去model化的。如果組件間調用不對參數做去model化的設計,就會導致業務形式上被組件化了,實質上依然沒有被完全獨立。其中的model并不是指架構中的model層,此處model化指的是模塊間使用數據對象傳值,去model化指的是模塊間不使用數據對象傳值。

三. 目標設定

組件化開發很重要的目的就是解耦合,提高開發效率。解耦的主要方式:

1. 把依賴的代碼先做成一個Pod庫,然后轉而依賴Pod庫,“依賴下沉”。

2. 使用category的方式把依賴改成組合的方式。

3. 使用一個block、delegate(協議)、通知等把這部分職責拋出去。

4. 直接copy代碼。避免業務干擾,也可以直接copy代碼來用,謹慎使用。

1、架構設計:層級架構+組件化架構

層級架構:只能上層對下層依賴,下層對上層不能有依賴,下層中不要包含上層業務邏輯,同層間的功能庫或組件之間都應無依賴關系。

image.png

組件化層級及拆分

組件化架構:處于層級架構的最上層,也就是業務層。各業務組件之間通過中心路由轉發調起其他組件的服務,并能獨立編譯、運行。

image.png

組件化架構圖

采取這種結構混合的方式進行整體架構,與項目當前的架構比較接近,方便組件化的推進,符合公司業務需求。

2、目標效果

1.  第三方庫管理、基礎庫、功能組件獨立

保證所有第三方庫管理、基礎庫、功能組件從主工程抽出,可獨立編譯,便于各業務模塊的調用。提高代碼復用率,提高業務開發效率。

2. 業務模塊劃分與拆解,獨立編譯

將業務按對應用功能或流程進行劃分和拆解,能夠單獨進行編譯、運行。保障各業務線開發相互獨立,減少業務耦合,方便 QA 有針對性地測試。

3. CocoaPods 發布私有庫,減少編譯時間

將穩定模塊打包成.a文件,做成私有庫,并對每個組件用 Pods  進行管理和后續更新工作。加快編譯速度,提高業務開發效率。

4. 通過模塊庫,提高代碼重構或搭建新產品線的效率

通過對模塊的組合配置或替換,能快速安全的替換舊的模塊庫,或快速搭建新的產品線,或將模塊庫擴展到其他產品線。

四. 制定計劃

首先要明白,不是重寫而是重構,是不改變軟件功能的前提下,調整軟件內部結構,優化項目管理,規范開發流程,提高開發效率,讓代碼更易讀,更好維護。

原則: 穩定、精簡、能夠重用、持續進行,最大程度的讓框架和業務分離,功能和業務分離。

1、在原項目的基礎上調整?

1.目前的結構經過改進還能滿足開發需要,項目擴展,沒必要“推到重來”。

2.項目一直在迭代開發,沒有足夠的人力和時間,去重寫項目,重寫項目的周期太長,并不能隨時中斷。

3.沒有單元測試,人員變動較大,熟悉業務的同事不多,重寫的風險極大。

4.項目歷史悠久,隱含配置較多,對舊系統的兼容配置,另外多是接管的代碼,代碼也沒有注釋,甚至注釋不匹配的情況。

5.邏輯相互耦合,拔出蘿卜帶出泥,遷移模塊時,關聯太多。

6.有可能過度設計,導致重寫計劃遲遲無法完成,也不能優化工作用到項目中。

總之,在原項目的基礎上逐步改進

2、風險評估控制

開始前預估工期,預估重構風險。

修改時,拉去新分支,要做到代碼隔離。

并詳細做好重構的細節記錄,如文件移動,文件改寫等重要操作文檔化,便于review,問題回歸,測試回歸。

每一個拆分出的模塊及時添加文檔,每一個模塊或組件的建立者把模塊內容、拆分目的、設計思路等基本信息記錄一下,有什么坑或者注意點也可以文檔化,是以后的長期項目維護成為可能。

3、組件化應分步推進

組件化是一個項目的整體調整,需要分階段,分批次的逐步重構。

每個階段大概的步驟:

1.明確該階段工作的重點,預估工期,預估重構風險。

2.拉取新分支,隔離重構代碼。

3.階段重構調整之后,需要半數組員做代碼review。

4.提交測試回歸相關功能。

5.將重構代碼整合到最近的發版中。

五. 實施計劃

1、一期:梳理項目工程結構,抽離基礎層和中間層

1. 項目工程定義

初步調整工程目錄結構如下:

基礎層和中間層

Pods: 僅Pods管理的第三方庫。

DDManualThirdSDKs: Pods不能管理的第三方庫,對第三方進行必要的封裝,集中做成私有庫的形式,再交給Pods管理。

DDDevelopLib: 自行封裝的私有庫,如系統類分類、數據處理類、通用UI組件、宏定義和常量定義等。做成私有庫,交給Pods管理。

業務組件層

DDEngine: 后續會把模型規整到具體模塊中,部分文件需要抽離到基礎層或中間層,其他暫時保持不變,后續抽離封裝網絡庫。

DDMIX_UI: 暫時保留,屬于三期。

ddDemo: 將其中的第三方庫、UILib、分類等,下沉到基礎層或中間層外,暫時保持不變。

2. 整理三方庫統一Pods管理

把項目中散落的第三方庫都規整到Pods和DDManualThirdSDKs工程中,優先Pods管理。

散落的第三方庫有:iflyMSC、libSunFlower、DDReader、YYText、MiaoZhen、NTalkerUIKitSDK、TalkingData、VoiceConvert、HPGrowingTextView(7年未維護了,局部使用,可以內化為自行代碼)等。

3. 梳理DDDevelopLib私有庫

自行封裝的私有庫,作為整個工程的基礎庫,不與具體的業務耦合,如系統類分類、數據處理類、通用UI組件、宏定義和常量定義等。做成私有庫,交給Pods管理。如ddDemo中的VerifyUpdate、UILib、DDAppkit、Common、Categorys、Function、DDMonkey等。

4. Resources文件整理

初步整理Resources資源文件,后期會根據資源情況再統一整理圖片資源,注意資源文件的加載路徑的變化后,保證資源文件能正常加載。

5. SupportingFiles文件整理

創建真實目錄SupportingFiles,存放系統支持文件如下:main.m、Info.plist、Prefix.pch、Debug.entitlements。

2、二期:梳理中心路由,搭建組件開發的模板框架

1.梳理跳轉中心

將跳轉中心的路由按業務組件進行分組。

2.創建一個組件的模板框架

每個組件,都有一個組件服務管理類,來管理對外能提供的服務列表和使用說明。

組件內的架構設計,使用MVC、MVP還是MVVM,根據各自情況合理選擇就好了。

3、三期:將組件化,擴展到整個項目,將穩定組件用pod管理

將穩定的組件打包成.a文件,進行pod管理。

將組件化,擴展到整個項目。

六. 常見問題及對應思路

1、組件化工時不好評估,工作進度難以控制

每個階段開始前都要做好技術調研和探討,少走些彎路,降低返工率。制定較為詳細的計劃表,做好工作分配,處理好業務開發與技術改造工作之間的關系,保障組件化能連續的進行。

2、分層結構不明確和橫向依賴

業務模塊之間也存在一些不合理的橫向依賴,沒有進行一個合理的業務邊界劃分。這些原因導致我們在進行拆分工作時經常需要回過頭來對已經拆出來的模塊和組件重新進行整理和處理,重復勞動量很大。采用先易后難的步驟,盡量下沉邏輯,橫向依賴,可以做一個下層抽取,變橫向依賴為上下層依賴。

3、拆分粒度大小不好把控

如單品頁組件中有單品主頁,評論頁,寫評論等較大的模塊,拆分力度不夠細,單品頁的信息會交織在一起。前期可以將業務關聯性強的模塊集合在一起,后期在逐個組件做細分拆解。

4、注意對代碼調整的控制

拆分過程中,會有重復代碼,甚至無用代碼,在做調整時要謹慎,尤其是公共類,保障邏輯不變的情況下酌情調整,設置不做修改,并做好記錄,方便review,請測試回歸。杜絕隨意改動,也不回歸測試。

作者:擇勢勤

鏈接:https://www.jianshu.com/p/1e1009ba061c

三国杀武将