上一篇文章發布之后又摸了小半年的魚,前段時間精神狀態確實很懶,寫的東西都帶有記流水賬的性質。所以這次決定寫點干貨。
換了新工作之后,到新公司接手了公司以前的老項目。整個項目都是用coordova、ionic混合開發完成的。啃了兩周的項目代碼之后,覺得之前留下的攤子確實不好收拾,和產品確認過眼神之后,果斷決定重啟爐灶。
具體過程就不多啰嗦了,雖然說的是混合開發,不過總體來說仍然是原生為主,部分頁面通過webview嵌入H5頁面的方式來做展示,并不是網上所謂的一站式混合開發。不過個人認為這種方式才是更符合當前需求的一種方式,至于所謂的ionic之類的,demo很美好,需求很殘酷。因為混合開發的緣故,從項目管理的角度和后期的維護性考慮,需要把H5相關的插件代碼和原生代碼分開,所以這里用到了模塊化開發的方式。雖然這個項目目前只有我一個人,不過也正好可以試驗一下自己以前想用而被上面無情pass掉的各種新技術。所以這篇文章主要介紹的是自己摸索并結合網上資料總結的一種組件化/模塊化開發方式。對于這兩種稱謂,我個人沒有太去糾結區別,所以下文可能會出現混用。本文的目的在于分享一種思路,大家就不要在意這些細節了。
-
需求場景
公司的老項目重構任務是要求把以前的ionic混合開發項目進行拆分,將大部分功能和主入口實現原生化,而商城這種業務變化較快的模塊仍然保持H5方式展示。在第一版本的時候因為時間關系,只做了基礎模塊和主入口的原生化,剩下的大部分模塊仍然是用老的coordova項目的代碼打了一個aar包進來加載。也是在這個時候,因為項目中嵌入了大量配合coordova的代碼,而這部分代碼下個版本是注定要扔掉的,作為一個有強迫癥的人,自然是不能容忍主項目里面有這些代碼的,所以模塊化的坑就這么挖起來了。
-
模塊化開發的優勢
一是結構清晰,各個模塊的代碼實現分離,不會攪在一起。在代碼review或者二次開發的時候一目了然,不會滿世界去找代碼。
二是協同開發的時候更靈活,不用再等同組其他同事的模塊開發完成后才能運行app,自己負責的模塊稍加修改就可以當做主app直接跑起來。
三是便于維護。每個模塊的代碼、布局文件、資源文件可以隨時從項目中通過gradle配置去除掉。 -
基本思路
公司接收的項目是一個貨運平臺app。按照功能劃分,有貨運模塊、交易模塊、貨源模塊、商城模塊和個人中心。其中后兩個是原項目的H5模塊中的老代碼,前三個是全部實現了原生化。所以基本結構就是原生入口,下分五個原生子頁面。后兩個原生子頁面加載webview進行H5頁面展示。
這里先附上一張基本的項目結構圖。
一個基本的項目結構下面來說說這個項目的結構是怎么一步步整個成這樣的。
1.基本結構
app模塊是每個項目初始都有的,實質上仍然是一個module。Android Stuido項目中,我們和代碼打交道的大部分時間都在module中。當然,具體的module機制我們不去深究,有時間可以另開一坑去研究。下面的三個module大家可以理解為java中的library,當然這樣說不準確。
按照之前的業務邏輯劃分,項目結構可以先大致分為如下的結構:
app作為主要的module,主要承擔了應用啟動以及最上層的通用邏輯。比如在這個例子中,應用啟動、首頁展示和模塊切換的業務邏輯都在這個模塊。
而下屬的三個子模塊承擔了各自細分的業務,并且可以被app模塊或者其他模塊引用,每個模塊只負責和考慮自己的業務。以此達到業務邏輯和代碼分離的邏輯。
其中的箭頭方向表示了引用關系2.系統層分離
當然,僅僅這樣是不夠的。因為這樣有一個問題,在AS中,module的引用是單向的。如果A module引用了B module,那么對A來講,B是可見的,B的所有公開功方法理論上都可以在A中使用,但是對B來說,A是不可見的。所以,相面這樣的結構出現的問題就是我們有大量的底層通用方法都放在app模塊中,對于子模塊來講是不可見的,子模塊無法引用封裝好的底層方法,例如網絡請求,圖片加載,文件拷貝等,這肯定是不行的。所以這個結構還得再優化。
按照module單向引用的原則,我們可以把公共底層通用方法單獨分出來作為一個moduleBase,同時這個moduleBase也是最底層的module,保證對于其他module來說它都是可見的。這樣還有一個好處就是這個moduleBase中的方法和配置大部分都是可以高度復用的。在新開其他項目的時候這個模塊可以直接遷移到新項目中,而不用在為代碼分離和剔除浪費時間。所以,項目的結構進一步細化成了如下的結構:
到這里,一個基本的結構就算完成了,但是這個結構仍然不完善。
上述的模塊如果在使用中,有很大概率會遇到一個問題,部分的實體類、自定義view、布局文件或者資源文件在各個模塊都需要用到,但是這些如果放在系統層的moduleBase里面,又會破壞系統層的通用性。所以,我們還需要一個公共層moduleCommon來專門提供上層業務邏輯模塊的公共資源。直接上圖:3.公共層分離
4.細化與擴展
其實在第三步之后整個項目結構已經算是比較完整了,不過隨著項目的不斷擴大,模塊仍然還是需要不斷細分。這里說一下整個項目結構的一種規劃思路。
在上述的項目結構中,嚴格來說只有三層:系統層、業務邏輯和app層。
其中app層是相對簡單的,只要包含應用啟動和初始化的一些額外操作和邏輯。而業務層包含了所有劃分出來的子功能模塊,為了方便項目結構的顯示方便,我們可以把這些模塊放在統一的文件夾下
":moduleUser"
變成":moduleCore:moduleUser"
,多級以次類推。同樣,對中間層我們也可以采用類似的方式,因為中間層不僅會包含一些我們自定義的通用實體類等文件,還有可能會有我們常用的二次封裝過的三方庫和開源庫。這些庫有些本身就是一個module需要我們引入,有些則是我們經過二次封裝的module。這些module同樣不適合放在系統層,所以也可以歸到公共層里,例如在我的項目里就有支付寶SDK,高德地圖等通用moudle
最后,附上完整的設計思路和項目結構:
到這里,一個基本的組件化項目結構就搭建完成了。這一部分主要是介紹了模塊劃分的邏輯和依據,偏向思想。實際開發過程中,因為各個module之間的引用關系還有很多的坑,這一部分我會在下一篇文章詳細說明。這里就不在贅述。
最后,這種組件化的結構只是自己在實際項目開發中自己結合網上的資料摸索出來的,并不一定是最好的或最合理的,如果各位有更好的方法或思路,歡迎大家留言交流。