B站Android程式碼庫的演進歷程
早在2012年,B 站 Android APP 便已上線。當時開發者不過一人,而如今,業務線眾多、隸屬不同團隊的Android 端開發人員數以百計。從單兵作戰到百花爭鳴,程式碼庫的組織管理也隨之經過數次的改革、演進。
單倉庫
2014年底,Android 端的常駐開發人員一隻手也數的過來。業務發展迅速,為追求效率,方便管理,所有程式碼都在一個倉庫中,甚至包括第三方的、開源的程式碼(個別用 git submodule 管理)。Clone下來匯入 Eclipse 就可以開幹。
到大約15年中旬,開始使用 Android Studio,得益於 Gradle 的專案管理理念,分出了多個 library module。外部依賴使用 maven。也是這一期間開始搭建了內網 maven 服務。
這期間程式碼庫組織結構是:單倉庫 + 個別 git submodule。
這種組織方式好處顯而易見:
- 專案結構簡單:隨時隨地 clone 下來匯入 IDE 即可以開始開發,程式碼所有人可見,沒有額外的限制。
- 方便快速迭代:改動可以快速入庫,適合小團隊,review方便,改動透明
但是,約莫到16年中,業務發展,新團隊紛紛成立,招聘要求降低人員迅速膨脹。這種小而美的程式碼庫已經不適用了,主要有以下缺點:
- 程式碼結構混亂,模組之間依賴關係混沌:倒不如說是技術債,前期的疲於業務迭代,以及沒有及時的規劃出好的程式碼層級架構,如今人員紛雜水平不一,之前追求的“沒有限制”反而誘發了惡果
- 編譯時間變長:業務增速發展,程式碼量爆炸式增長,單機編譯越來越慢,開發幸福感跌到谷地
多倉庫
一個字:“拆”。
單倉庫裡,所有能切出去的、划走的,甭管橫的來按業務分、豎的走按層級分,都拆出去,最好倉庫中只留一個光桿app模組,最終只剩下拆無可拆的模組,所有依賴的模組都預先編譯好上傳到maven。期間冠名曰:元件化。
約到17年中,這些拆出來的模組,一些獨立為倉庫,一些按所屬層級聚攏到一起合為一個倉庫。業務模組為了快速除錯,一般會寫一個demo app 模組用作測試。
此時程式碼庫組織結構是:多倉庫。
好處是:
- 隔離性十足:按業務劃分的模組所屬倉庫,倚托於gitlab許可權管理,“外人”決計無法修改自己的程式碼。
- 依賴關係清晰:自上而下,由外而內。更容易做到高內聚低藕合。
- 編譯速度快:大部分依賴都預編譯後上傳到maven,比起之前從原始碼編譯的速度不知道快到哪裡去了
但是…
隨著業務線發展、人員的進一步擴張,不到一年時間,多倉庫的缺點也快速暴露了出來:
- 維護複雜:尤其是模組之間有依賴關係時,修改依賴版本號是個重要、重複且容易出錯的操作。且不便於review不便於快速暴露修改導致的相容性問題,更進而影響其它模組進度。歷史包袱重,比如由於離職等原因導致責任人丟失,非常難梳理出所有模組的修改歷史,多個團隊協同開發的時候難上加難
- 程式碼重複:由於程式碼分散倉庫存放,天然的隔離更容易產生互相拷貝的問題。另外也容易產生相同功能的重複開發,如由不同的人作一個類似的模組,但彼此不知。
- 過分隔離:由於團隊的不同,協作工作流程長且所涉人員多,溝通成本非常之高,開會從早到晚,一線開發人員一般只轉注於自己的模組,當一個螺絲釘,無法從專案整體視角看問題,進而又導致專案結構趨於混亂、依賴關係複雜化。
大倉
“大倉”—— 一個來自B站 Go 團隊率先實踐過切實可行的方案映入眼簾。
大倉,來自英文 Monotonic Repository (簡稱monorepo)。望文生義,即一個倉庫,包羅永珍海納百川。源自西方大廠們(Google/Facebook/…)一致叫好的實踐良久的程式碼管理方案。
說到底其實就是一開始的“單倉庫”的進化版。與純粹的“單倉庫”不同的地方是,有眾多的工具鏈來維持大倉的日常開發,而非人力,是工程師文化中“不重複勞動”的極致化體現。
關於大倉,這裡不費篇幅去過多解釋了,請自行 Google
目前(2019/1/3),因為站在巨人的肩膀上,先行者已經準備好了一部分的工具鏈(gitlab-ci, saga等),B站 Android 團隊已基本完成大倉的組建。
依然遵循之前規劃的架構以及元件化的思想,將目錄結構約定為形如:
<root dir>
├── app
│ ├── main
│ ├── live
│ ├── bangumi
│ ├── ...
│
├── common
│ ├── ...
│
├── framework
│ ├── ...
│
└── entrance
依賴關係約定,app -> common -> framework
好處自不必多說,先說其侷限性:
- 龐大而臃腫: clone專案和匯入所有程式碼對開發機器是個挑戰(為此我已經更換新款MBP~~)。但可以通過編譯配置以及git sparse-checkout解決
- git-flow混亂: 因為之前不同團隊不一樣的git-flow,先天的認知不一,另外個別人對git操作理解不深,會導致出現一些人為因素上的合丟程式碼
對於Android 大倉如何組成,如何解決上述問題,下一篇會給大家分享 歡迎關注
總結
所謂“分久必合,合久必分”,單倉庫也好,多倉庫也罷,都是為了解決業務上的問題而生。
從來沒有放之四海皆準的方案,千萬不要脫離業務談架構,選擇適合自己團隊的方案才是好方案。
早在2012年,B 站 Android APP 便已上線。當時開發者不過一人,而如今,業務線眾多、隸屬不同團隊的Android 端開發人員數以百計。從單兵作戰到百花爭鳴,程式碼庫的組織管理也隨之經過數次的改革、演進。
單倉庫
2014年底,Android 端的常駐開發人員一隻手也數的過來。業務發展迅速,為追求效率,方便管理,所有程式碼都在一個倉庫中,甚至包括第三方的、開源的程式碼(個別用 git submodule 管理)。Clone下來匯入 Eclipse 就可以開幹。
到大約15年中旬,開始使用 Android Studio,得益於 Gradle 的專案管理理念,分出了多個 library module。外部依賴使用 maven。也是這一期間開始搭建了內網 maven 服務。
這期間程式碼庫組織結構是:單倉庫 + 個別 git submodule。
這種組織方式好處顯而易見:
- 專案結構簡單:隨時隨地 clone 下來匯入 IDE 即可以開始開發,程式碼所有人可見,沒有額外的限制。
- 方便快速迭代:改動可以快速入庫,適合小團隊,review方便,改動透明
但是,約莫到16年中,業務發展,新團隊紛紛成立,招聘要求降低人員迅速膨脹。這種小而美的程式碼庫已經不適用了,主要有以下缺點:
- 程式碼結構混亂,模組之間依賴關係混沌:倒不如說是技術債,前期的疲於業務迭代,以及沒有及時的規劃出好的程式碼層級架構,如今人員紛雜水平不一,之前追求的“沒有限制”反而誘發了惡果
- 編譯時間變長:業務增速發展,程式碼量爆炸式增長,單機編譯越來越慢,開發幸福感跌到谷地
多倉庫
一個字:“拆”。
單倉庫裡,所有能切出去的、划走的,甭管橫的來按業務分、豎的走按層級分,都拆出去,最好倉庫中只留一個光桿app模組,最終只剩下拆無可拆的模組,所有依賴的模組都預先編譯好上傳到maven。期間冠名曰:元件化。
約到17年中,這些拆出來的模組,一些獨立為倉庫,一些按所屬層級聚攏到一起合為一個倉庫。業務模組為了快速除錯,一般會寫一個demo app 模組用作測試。
此時程式碼庫組織結構是:多倉庫。
好處是:
- 隔離性十足:按業務劃分的模組所屬倉庫,倚托於gitlab許可權管理,“外人”決計無法修改自己的程式碼。
- 依賴關係清晰:自上而下,由外而內。更容易做到高內聚低藕合。
- 編譯速度快:大部分依賴都預編譯後上傳到maven,比起之前從原始碼編譯的速度不知道快到哪裡去了
但是…
隨著業務線發展、人員的進一步擴張,不到一年時間,多倉庫的缺點也快速暴露了出來:
- 維護複雜:尤其是模組之間有依賴關係時,修改依賴版本號是個重要、重複且容易出錯的操作。且不便於review不便於快速暴露修改導致的相容性問題,更進而影響其它模組進度。歷史包袱重,比如由於離職等原因導致責任人丟失,非常難梳理出所有模組的修改歷史,多個團隊協同開發的時候難上加難
- 程式碼重複:由於程式碼分散倉庫存放,天然的隔離更容易產生互相拷貝的問題。另外也容易產生相同功能的重複開發,如由不同的人作一個類似的模組,但彼此不知。
- 過分隔離:由於團隊的不同,協作工作流程長且所涉人員多,溝通成本非常之高,開會從早到晚,一線開發人員一般只轉注於自己的模組,當一個螺絲釘,無法從專案整體視角看問題,進而又導致專案結構趨於混亂、依賴關係複雜化。
大倉
“大倉”—— 一個來自B站 Go 團隊率先實踐過切實可行的方案映入眼簾。
大倉,來自英文 Monotonic Repository (簡稱monorepo)。望文生義,即一個倉庫,包羅永珍海納百川。源自西方大廠們(Google/Facebook/…)一致叫好的實踐良久的程式碼管理方案。
說到底其實就是一開始的“單倉庫”的進化版。與純粹的“單倉庫”不同的地方是,有眾多的工具鏈來維持大倉的日常開發,而非人力,是工程師文化中“不重複勞動”的極致化體現。
關於大倉,這裡不費篇幅去過多解釋了,請自行 Google
目前(2019/1/3),因為站在巨人的肩膀上,先行者已經準備好了一部分的工具鏈(gitlab-ci, saga等),B站 Android 團隊已基本完成大倉的組建。
依然遵循之前規劃的架構以及元件化的思想,將目錄結構約定為形如:
<root dir>
├── app
│ ├── main
│ ├── live
│ ├── bangumi
│ ├── ...
│
├── common
│ ├── ...
│
├── framework
│ ├── ...
│
└── entrance
依賴關係約定,app -> common -> framework
好處自不必多說,先說其侷限性:
- 龐大而臃腫: clone專案和匯入所有程式碼對開發機器是個挑戰(為此我已經更換新款MBP~~)。但可以通過編譯配置以及git sparse-checkout解決
- git-flow混亂: 因為之前不同團隊不一樣的git-flow,先天的認知不一,另外個別人對git操作理解不深,會導致出現一些人為因素上的合丟程式碼
對於Android 大倉如何組成,如何解決上述問題,下一篇會給大家分享 歡迎關注
總結
所謂“分久必合,合久必分”,單倉庫也好,多倉庫也罷,都是為了解決業務上的問題而生。
從來沒有放之四海皆準的方案,千萬不要脫離業務談架構,選擇適合自己團隊的方案才是好方案。
歡迎加入Android進階交流群;701740775。進群可免費領取一份最新技術大綱和Android進階資料。請備註csdn
相關文章
- Javascript模組化的演進歷程JavaScript
- CnosDB有主複製演進歷程
- 滴滴 Redis 異地多活的演進歷程Redis
- 阿里雲的“全站加速”技術演進歷程阿里
- BERT預訓練模型的演進過程!(附程式碼)模型
- 荔枝架構實踐與演進歷程架構
- 騰訊劉穎:從容器到低程式碼,騰訊雲原生技術演進歷程
- B站公網架構實踐及演進架構
- 應用閘道器的演進歷程和分類
- 阿里巴巴在 Envoy Gateway 的演進歷程淺析阿里Gateway
- Angular Universal 的演進歷史Angular
- 一文讀懂資料平臺建設的演進歷程
- 氣泡排序的演變過程及程式碼演示排序
- B站故障演練平臺實踐
- Java分散式架構的演進過程Java分散式架構
- 萬表商城Android架構演進Android架構
- 我經歷過的監控系統演進史
- 《六週玩轉雲原生》- 微服務架構下服務治理體系的演進歷程?微服務架構
- 大型網站架構演化歷程網站架構
- 圖解分散式架構的演進過程!圖解分散式架構
- 淘寶10年的架構演進過程架構
- 記寫 android 微信登入的demo歷程Android
- 最新進展!谷歌AutoML-Zero驗證自我演化:成功復現數十年AI演進歷程谷歌TOMLAI
- 軟體自動化測試工具的歷史演進
- 文件知識庫的演進和小結
- 淺談儲存器的進化歷程
- 敏捷過程中的障礙板演進與AI敏捷AI
- Code:美團程式碼託管平臺的演進與實踐
- BlazorCharts 原生圖表庫的建設歷程Blazor
- GIS轉碼的秋招歷程與踩坑經歷
- 大型分散式架構的演進歷史(前方多圖告警)分散式架構
- 聊一聊我在 B 站自學 Java 的經歷吧Java
- Maven中央倉庫釋出歷程Maven
- 7000 字讀懂網際網路公司的架構演變歷程架構
- 程式的一生:從源程式到程式的辛苦歷程
- 大型網站架構演化發展歷程網站架構
- 服務架構學習與思考(12):從單體架構到微服務架構的演進歷程架構微服務
- B站直播間基於檢視互動的架構演進架構