本文已受權微信公衆號 AndroidDeveloper 獨家發佈。java
入職安居客三年從工程師到 Team Leader,見證了 Android 團隊一路走來的發展歷程。所以有心將這些記錄下來與你們分享,也算是對本身三年來一部分工做的總結。但願對你們有所幫助,更但願能獲得你們寶貴的建議。android
三年前入職時安居客在業務上剛完成了三網合併(新房、二手房、好租和商業地產多個平臺多個網站合成如今的 anjuke.com,這在公司的歷史上稱之爲三網合併),所以移動端也將原先的新房、二手房、好租和商業地產多個 App 合併成爲了如今的安居客 App。所謂的合併也差很少就是將多個項目的代碼拷貝到了一塊兒組成了新的 Anjuke Project。下面這張圖能更加直觀的呈現當時的情況:git
這一時期代碼結構混亂、層次不清,各業務技術方案不統一,冗餘代碼充斥項目的各個角落;甚至連基本的包結構也是胡亂不堪,項目架構更是無從談起。你們只不過是不停地往上堆砌代碼添加新功能罷了。因而我進入公司的第一件事就是向 Leader 申請梳理了整個項目的結構。github
然後隨着項目的迭代,咱們不斷引入了 Retrofit、UniversalImageLoader、OKHttp、ButterKnife 等一系列成熟的開源庫,同時咱們也開發了本身的 UI 組件庫 UIComponent、基礎工具庫 CommonUtils、基於第三方地圖封裝的 MapSDK、即時聊天模塊 ChatLibrary 等等。這以後安居客項目架構大體演變成了由基礎組件層、業務組件層和業務層組成的三層架構。以下圖:數據庫
其中業務層是一種非標準的 MVC 架構,Activity 和 Fragment 承擔了 View 和 Controller 的職責:微信
前面這種分層的架構自己是沒太大問題的,即便到了如今咱們的業務項目也已然是基於這種分層的架構來構建的,只不過在不斷的迭代中咱們作了些許調整(分層架構後面在介紹組件化和模塊化的時候會詳細介紹)。可是隨着業務的不斷迭代,咱們慢慢發現業務層這種非標準的MVC架構帶來了種種影響團隊開發效率的問題:網絡
鑑於三網合併時期我還未加入安居客,因此對這一塊的理解不免有誤差,若是有安居客的老同事發現文章中的描述有不對的地方還望批評指正。架構
一種技術架構沒法知足全部的業務項目,更不可能有一種架構方案可以一勞永逸。正如上一節中提到的隨着業務的不斷迭代,現有架構的缺陷逐漸浮出水面,項目架構必需不斷升級迭代才能更好地服務於業務。app
在研究了 Google 推出的基於 MVP 架構的 Demo 後,咱們發現 MVP 架構能解決如今所面臨過的不少問題,因而咱們學習並引入到了咱們的項目中來,並針對性的作了部分調整。下圖呈現的是安居客 MVP 方案:框架
之前面提到的三層架構的方案來看是這樣的:
基於此架構我在 GitHub 上開源了一個項目MinimalistWeather,有興趣的小夥伴能夠去 Clone 下來看看,若是以爲對你有幫助就給個 Star 吧。 :)
另外這套MVP架構還爲咱們帶來了一個額外的好處:咱們有了足夠明確的開發規範和標準。細緻到了每個類應該放到哪一個包下,哪一個類具體應該負責什麼職責等等。這對於咱們的 Code Review、接手他人的功能模塊等都提供了極大的便利。前面提到的 MinimalistWeather 就是爲了定規範定標準而開發的。
這一時期咱們還在項目中引入了 RxJava,很好的解決了前面提到的嵌套回調的問題,同時可以幫助咱們簡化複雜業務場景下的代碼邏輯(固然 RxJava 的好處遠遠不止這麼一點,對 RxJava 不瞭解的同窗能夠去翻翻我以前一系列關於 RxJava 的文章)。咱們也將網絡庫升級到了 Retrofit2 + OKHttp3,它們和 RxJava 之間能更好的配合。
是否是升級到了 MVP 架構就高枕無憂了呢?很明顯不是這樣!MVP 架構也會帶來如下新的問題:
去年下半年咱們 Android 團隊內部成立了技術小組,基礎組件的開發是技術小組很重要的一部分工做,因此組件化是咱們正在作的事;模塊化更多的是現有的方案受到來自業務上的挑戰以及受到了 Oasis Feng 在 MDCC 上的分享和整個大環境的啓發,如今正處於設計規劃和 Demo 開發的階段。
組件化不是個新概念,通俗的講組件化就是基於可重用的目的,將一個大的軟件系統拆分紅一個個獨立組件。
組件化的帶來的好處不言而喻:
如今的安居客有是三個業務團隊:安居客用戶 App、經紀人 App、集客家 App。爲了不各個業務團隊重複造輪子,團隊中也須要有必定的技術沉澱,所以組件化是必須的。從本篇的第一節你們就能看到組件化的影子,只不過在這以前咱們作的並很差。如今咱們須要提供更多的、職能單1、性能更優的組件供業務團隊使用。根據業務相關性,咱們將這些組件分爲:基礎組件和業務組件。後面在介紹模塊化的時候會有進一步的描述。
自從 Oasis Feng 在去年的 MDCC2016 上分享了模塊化的經驗後,模塊化在 Android 社區愈來愈多的被提起。咱們天然也不落俗的去作了一些研究和探索。安居客如今面臨不少問題:例如全量編譯時間太長(我這臺13款的 MacBook Pro 上打一次包得花十多分鐘);例如新房、二手房、租房等等模塊間耦合嚴重,不利於多團隊並行開發測試;另外在17年初公司從新將租房 App 撿起推廣,單獨讓人來開發維護一個三年前的項目並不划算,因此咱們但願能直接從如今的安居客用戶端中拆分出租房模塊做爲一個單獨的 App 發佈上線。這樣看來模塊化彷佛是一個不錯的選擇。
因此咱們作模塊化的目的大體是這樣的:
15年 Trinea 還在安居客的時候開發了一套插件化框架,但受限於當時的團隊規模而且插件化對整個項目的改造太大,所以在安居客團隊中插件化並未實施下來。而模塊化實際上是個很好的過渡方案,將項目按照模塊拆分後各業務模塊間解耦的問題不存在了,後續若有必要,再進行插件化改造只不過是水到渠成的事。
來看看安居客用戶 App 的模塊化設計圖:
整個項目分爲三層,從下往上分別是:
同時針對模塊化咱們也須要定義一些本身的遊戲規則:
對於模塊化項目,每一個單獨的 Business Module 均可以單獨編譯成 APK。在開發階段須要單獨打包編譯,項目發佈的時候又須要它做爲項目的一個 Module 來總體編譯打包。簡單的說就是開發時是 Application,發佈時是 Library。所以須要你在 Business Module 的 Gradle 配置文件中加入以下代碼:
if(isBuildModule.toBoolean()){
apply plugin: 'com.android.application'
}else{
apply plugin: 'com.android.library'
}複製代碼
若是咱們須要把租房模塊打包成一個單獨的租房 App,像下面這樣就好:
咱們能夠把 Basic Component Layer 和 Business Component Layer 放在一塊兒看作是 Anjuke SDK,新的業務或者項目只須要依賴 Anjuke SDK 就好(這一點一樣是受到了 Trinea 文章的啓發)。甚至咱們能夠作得更極致一些,開發一套本身的組件管理平臺,業務方能夠根據本身的需求選擇本身須要的組件,定製業務專屬的 Anjuke SDK。業務端和 Anjuke SDK 的關係以下圖所示:
最後看看安居客模塊化的總體設計圖:
模塊化拆分對於安居客這種比較大型的商業項目而言,因爲歷史比較久遠不少代碼都運行五六年了;各個業務相互交叉耦合嚴重,因此實施起來仍是有很大難度的。過程當中不免會有預料不到的坑,這就須要咱們對各個業務有較深的理解同時也要足夠的耐心和細緻。雖然辛苦,可是一旦完成模塊化拆分對整個團隊及公司業務上的幫助是很大的。
以上是個人簡單總結以及對模塊化的一些思考,不足之處還望你們批評指正。後面模塊化的 Demo 完善後我會把它放到 GitHub,並再出一篇文章詳細介紹模塊化的設計實現細節。
參考資料:
若是你喜歡個人文章,就關注下個人知乎專欄或者在 GitHub 上添個 Star 吧!
- 知乎專欄:zhuanlan.zhihu.com/baron
- GitHub:github.com/BaronZ88