項目大了,編譯慢了,開發效率低了,怎麼辦? 也許你已經知道了組件化,但項目迭代任務緊張,根本沒有時間進行總體解耦,更懼怕一會兒改動太大致使的風險不可控,不敢大改,怎麼辦?git
先別急着放棄,漸進式組件化了解一下github
在實行組件化改造以前,咱們對業內的一些技術文章及開源庫進行調研以後,發現基本上千篇一概地都是基於路由這種方案做爲通訊引擎來實現組件化,重要的是組件化以前得先解耦原來的項目代碼。很尷尬,咱們沒那麼人力和時間來一會兒作這麼一大塊事情。這時候咱們是這樣想的:web
可不能夠先不解耦?windows
這個問題問得好,但是...不先解耦,組件怎麼單獨以app運行呢?
複製代碼
新業務新module能夠無耦合,總能夠單獨運行調試了吧?app
組件須要登陸怎麼辦?
須要跟其它組件通訊怎麼辦?
複製代碼
用URLScheme來跨app通訊總能夠了吧?框架
頁面跳轉還行,雖然有個中轉頁面,僅在開發期間使用勉強也能接受
但如何獲取服務?那但是要查找接口的實現類,跨app調用時行嗎?
複製代碼
將須要調用的業務代碼一塊兒打包總能夠了吧?maven
確實能夠,但這些代碼在哪裏?主app module看一下?
難不成要跟主app一塊兒打包?沒解耦的那些module要所有編譯才行哦
複製代碼
那...有沒有這樣一種方案:讓咱們能夠當即就在新的業務上用組件化的形式進行開發(單組件module以apk的形式編譯運行調試,而且能夠與其它業務模塊互相通訊),享受到組件化編譯速度快、調試效率高的好處,又不須要立刻解耦項目,而是在迭代過程當中利用偶爾出現的碎片空閒時間來一個一個慢慢地解耦呢?組件化
好想法,這就是咱們想要的:當即組件化開發 & 漸進式組件化改造
不過很遺憾,好像沒有什麼現成的方案可用。
那咱們就本身設計一個吧!
複製代碼
正式因爲項目代碼耦合度高,解耦困難,並且迭代任務緊張,沒辦法單獨抽出時間來解耦,致使組件化改造一直停留在口頭上。post
爲了在不影響業務迭代業務開發的前提下也能用組件化的形式來進行開發,咱們設計了一個支持當即組件化開發 & 漸進式組件化改造的框架:CC(已開源,點這裏看源碼)測試
以i百聯App爲例(上海百聯集團旗下的一個電商App)來看一下組件化以前項目中存在的耦合狀況:
最終項目的耦合狀態是這個樣子的(一個圓圈表明一個模塊,圓圈交叉表明存在耦合狀況):
爲了能讓你們看得清楚,圖片上僅僅列出了有限的幾個模塊,但即便是這樣,咱們用一團亂麻來形容它也絕不爲過。
咱們的工程師一直是在這樣的環境下進行業務迭代開發和bug修復,改代碼要當心翼翼,生怕引發其它邏輯出bug,最主要的是開發/調試效率很是低:在使用了maven的狀況下,在15吋高配的macbook pro上編譯運行每次都要花3-5分鐘,在16GB內存的windows臺式機上更是動輒10-15分鐘,嚴重影響開發效率,組件化勢在必行。
但業務迭代排期時間很是緊張,測試資源不足,咱們須要的是:當即組件化開發 & 漸進式組件化改造
在瞭解漸進式組件化改造以前,先來看看與之相對的非漸進式組件化改造
非漸進式的組件化方案要求咱們必須在組件化初期當即對項目進行解耦,至少是咱們須要被新業務調用到的組件須要解耦成組件,不然新業務組件脫離主app單獨運行調試的時候沒法正常工做。
在漸進式組件化的方案中,能夠先不用解耦,只須要讓單獨運行的組件可以調用到主App中的功能便可。思路是這樣的:
旁白:
IComponent
接口的實現類,對外暴露自身提供的服務,而且能夠獨立編譯運行調試IComponent
接口實現類,對外暴露自身的服務,讓會員積分組件可以跨App調用到這些組件IComponent
接口實現類,對外暴露自身的服務,讓瀏覽記錄組件可以跨App調用到商品詳情組件IComponent
對應多個組件),等未來有時間了再繼續拆分首先,CC的核心通訊引擎採用的不是路由方案,而是組件總線方案(路由 vs 組件總線)
CC採有2套調用流程:App內部組件調用和跨App調用。
框架在接收到組件調用請求時,優先查看當前App內是否有本次CC調用指定的組件
採用組件總線的方案,在App內部調用組件時,等效於直接調用IComponent.onCall(cc)
方法,將調用方設置的調用參數傳遞給組件,組件執行完以後將執行結果返回給調用方,這個過程當中沒有使用反射,執行效率高
在這個過程當中,CC完成了一次調用請求的轉發:查找到組件對象,並將調用其onCall方法,將調用參數發送給它,並將組件執行的結果返回給調用方
悄悄地告訴你:CC中自帶3種AOP策略,例如動畫中顯示的CustomerInterceptors
就是其中之二:全局攔截器和針對本次CC調用的攔截器。定義一個攔截器也很簡單:實現IGlobalCCInterceptor
接口便可
經過RemoteCCInterceptor
與另外一個App的ComponentService
創建鏈接,將CC中的調用參數傳遞給ComponentService
,在ComponentService
中使用這些參數,發起一個App內部的CC調用,最終經過LocalCCInterceptor
調用到IComponent.onCall(cc)
。
組件的執行結果原路返回給調用方
在這個過程當中,CC完成了2次調用請求轉發:
能夠看出,跨App調用時:
IComponent.onCall(cc)
方法也是在LocalCCInterceptor
中調用,與在App內部調用時同樣本文從咱們在實際實施組件化過程當中的一些思考入手,引入了漸進式組件化的概念,介紹了用CC來實現當即組件化開發 & 漸進式組件化改造的實施步驟。
並用動畫的方式向你們展現了漸進式組件化與非漸進式組件化的區別以及支撐CC實現漸進式組件化的組件調用流程。
本文中的圖片及動畫取自上週末(6月9日)在愛奇藝移動技術沙龍分享時的演講稿,PPT文檔可在CC交流羣(QQ羣:686844583)的羣文件中下載,歡迎加羣交流。
點擊這裏瞭解關於CC的更多內容