你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 手機天貓解耦之路

手機天貓解耦之路

編輯:IOS開發基礎

2813168_100421023_2.jpg

在GMTC官網可以下載這次分享的資料:http://ppt.geekbang.org/slide/show/194

現場視頻已上線:《手機天貓解耦之路》現場

本文標題是解耦,聊解耦可以有很多方法,本文以架構進化為線索給各位分享手機天貓的解耦之路。我想,在手機天貓的成長過程中,一些形而上的思考和沉澱固然是對大家有參考價值的,而工具和方案則借鑒價值更大。所以本文會較少篇幅放在講過程和原因,比較多篇幅放在講工具和方案。

什麼在推動進化

TB1nEl.OpXXXXbVapXXXXXXXXXX-2398-926.png

作為技術團隊,我們升級技術架構有各種原因,而什麼什麼因素是最關鍵的,什麼可以成為進化理由?

  • 業務升級

最重要的因素一定是業務升級。一個不能產生業務價值的技術是不值得關注的,更不值得去實施。

好技術永遠要比業務先走一步,在前邊不遠的地方等著業務追上來——技術驅動業務。所以業務不斷升級,就要求我們的技術架構要跑的更快。

  • 團隊規模 & 合作模式

另一個推動架構進化的重要因素就是團隊規模。技術架構最重要的作用之一是保障生產效率和生產質量。那麼人的因素就非常關鍵。人多了,合作復雜了,技術架構就必須升級,去保障這麼多人在一起工作的時候,效率高,不出問題。

  • 代碼規模 & 工程規模

代碼和工程的規模是一個自然發展的結果,業務復雜了,團隊大了,人多了,代碼規模和工程規模必然上升。一個數十萬DAU的App和一個千萬DAU的App,規模上的差距雖不是必然,卻也是極大概率了。

一個人,幾十個文件,完成一個簡單功能的產品,和十幾個人,數千個文件,功能復雜的產品,進一步到十幾個團隊,數百個模塊,一個平台及產品的技術架構必然千差萬別。

  • 新技術

新技術,就是工程師自己的事了。業界總會有新的技術出來,這個技術可能是別人家工程師,為了適應他們的業務發展和架構演化而研發出來的。但是技術沒有邊界,新技術好,能給我們帶來價值,提升我們的效率,那我們就拿來用。

舉個例子:Facebook的RN出來,我們都覺得不錯,應該也有很多公司確實大規模的使用了。大規模的使用RN做開發,也就會對你原本的架構提出升級的要求。

當然更重要的是如何去平衡快速升級技術架構的好奇心和恰好滿足業務與團隊要求這兩件事。過度追求技術架構革新,過度追求新技術,不但不能給業務和團隊帶來推動作用,反而會造成災難。所以,作為一個優秀的技術團隊永遠要權衡做或不做,多做或少做。

架構怎麼進化

架構進化體現在哪些方面,作為一個技術團隊我們要如何把架構進化落地?這個問題因項目而異,因團隊而異,因方向而異。本文只介紹手機天貓在發展過程中,與解耦相關的進化歷程。

  • 升級開發模式

開發模式的概念有點大,本文就只討論和解耦這件事相關的:團隊合作方式和工程組織形式。下文單獨一節聊這個事,此處不贅述。

  • 各維度解耦

工程大了以後,要分拆,不管是組件化還是插件化,還是什麼,解耦是第一步,而且是各個維度的解耦。

  • 完善工具集

模式演進的過程中,解耦的過程中,就會衍生出很多的工具。在進化過程裡我們也會去思考,哪些工作是需要工具化的,主動去開發工具。一個完善的工具集,會極大提升團隊的生產力,可以說是最有價值的部分。

開發模式升級

手機天貓團隊從一個三端不到十個人的小團隊,成長到現在一個接近兩百人的大團隊,後文詳細描述開發模式經歷了怎麼樣的變更?

  • 一個工程

三年前,手機天貓團隊剛剛組建,十個左右工程師,開發第一版只具備基礎功能的天貓App。整個團隊就這麼幾號人,包括iOS,Android和Server三端,一個平台上也就三四個人;App的功能也非常簡單,能完成基本的導購和交易流程。

天貓App就使用了最簡單的架構,獨立工程,MVC架構。而且我們判斷在這種情況下這樣的架構是完全夠用的,事實如此。

  • 模塊化

隨著無線業務的發展,手機天貓的團隊開始爆炸式的擴張。很快一個團隊變兩個,兩個變四個。隨著團隊增加,出現團隊分工,工程也越來越大,我們開始發現原始的架構已經開始不夠用,拆分模塊勢在必行。

在這個階段,手機天貓的模塊拆分也做得非常簡陋。先按功能把工程做橫向分層,在業務層再做縱向梳理。把不同的模塊代碼簡單的放在一個文件夾裡,而工程的組織形式並沒有發生變化。

如此拆分,我們做到代碼獨立,跨團隊基本不會在同一個模塊代碼上產生沖突。

  • 插件化

進一步發展,業務越來越復雜,團隊工作越發細分,人也越來越多,代碼量越來越大。簡單的使用文件夾來組織模塊的方式顯得力不從心。多業務跨團隊,不同的開發節奏,復雜的依賴關系,導致我們會花掉大量的時間解決編譯不過的問題。等待其他模塊集成這件事居然成了我們開發效率最大的瓶頸。

如何解決這個問題,我們的方案是插件化。那麼插件和模塊有什麼區別?我認為二者最大的區別在於獨立性。插件是可以獨立開發,獨立發布,獨立運行的,而模塊則必須依賴主工程的環境。具備獨立性的插件可以很好的隔離跨團隊之間的依賴,彼此獨立開發,按照各自的節奏發布版本。

基於這樣的思考,我們引入依賴管理設施(iOS引入了Cocoa Pods,Android使用Maven);把此前的模塊進一步剝離成獨立工程,單獨做版本管理;每個獨立的插件對發布的版本號負責,不論是其他插件還是主工程都依賴插件發布的穩定版本。

然而,但是,But,插件化這件事並沒有我們想象的那麼美好。代碼出來了,但是不能獨立編譯,依賴管理設施有了,但是管不好。由於我們此前從未梳理過依賴關系,所以不管是模塊還是插件,只是一種代碼管理和發布流程的工作法,解決不了獨立開發和獨立運行的問題。在這個階段,我們選擇了容忍這個問題,因為獨立開發和獨立運行這兩件事對我們來說似乎並不是那麼的有價值,而無法實現這兩件事也並不成為我們的瓶頸。所以大家還是在一個工程裡,只是代碼提交到不同的倉庫,然後通過依賴管理設施,通過版本號拼裝成主工程,源代碼最終運行還是揉在一起。

  • 獨立發布

無法獨立發布會帶來什麼問題?非常明顯,慢!插件化一段時間後,我們發現慢的問題嚴重影響著我們的效率。在這個階段,我們已經有超過十個團隊,iOS工程的源碼文件超過一萬個。由於主工程是通過各插件的源碼組合起來的,每一次重新索引和編譯,都要消耗超過半個小時的時間。

要解決這個問題,就是要把插件化進行到底,實現插件的另外兩個獨立——獨立開發和獨立運行。最重要的工作就是我們今天的主題解耦,梳理各個插件之間的依賴關系。讓每一個獨立插件盡可能少的依賴其他插件,在最小范圍內正常編譯執行。每次發布不再是一個穩定版本號,而是一個穩定的二進制包。

如此依賴,我們把超過半小時的編譯過程拆分到數十個模塊中,而主工程依賴數十個二進制包,編譯也就快了。

整個模式升級基本上經歷了這樣幾個階段:

1.代碼獨立,先從形式上解耦

2.獨立代碼工程化,為獨立運行打下基礎

3.梳理依賴關系,獨立工程可編譯

4.放棄源碼依賴,提速集成編譯

一路走來,一步一個腳印,最終實現完整的解耦。在這個過程中我們沉澱了不少的方法論和最佳實踐,我想有兩個工具是值得介紹的,下文詳述。

解耦工具箱

工欲善其事,必先利其器。這句話每個人都在說,卻不是每個人都能做到。一個具有工具文化的團隊會在質量,效率各個方面都會有很大優勢。

一個工程,從原始狀態迅速膨脹到天貓現在的體量的,依賴關系之復雜,超乎想象。

在這個膨脹過程裡,我把耦合分成三類:

  1. 界面耦合,就是用戶操作流程裡,從首頁-到搜索-到詳情-再進店,這些界面的跳轉是硬編碼的

  2. 依賴耦合,顧名思義,兩個模塊之間的有依賴,就是耦合

  3. 工程耦合,每個模塊有自己的生命周期和運行時,每個模塊在生產環境裡又需要依賴主工程的運行時

  • Beehive(Beehive已經開源,可以在Github上看到源碼:https://github.com/alibaba/BeeHive)

Beehive是一個運行時框架,主要解決依賴耦合和工程耦合。

說到耦合,體量如手機天貓這樣的一個App,各種依賴關系必然非常復雜,模塊與模塊的耦合也必然千絲萬縷。我們要做的並不是把這些依賴和耦合一一處理掉,而是進行梳理,把不合理的找出來,解決掉,讓整個工程處在一個健康合理的依賴和耦合范圍內。有問題的依賴基本有這樣幾種:

  1. 模塊循環依賴

  2. 層間反向依賴

  3. 非強功能依賴

下圖是一張依賴的示意圖。

TB1GGCEOpXXXXbdXXXXXXXXXXXX-354-326.png

幾條虛線的依賴關系是我認為有問題的依賴,而抽象出有問題的幾個模塊

TB1mXR5OpXXXXcQapXXXXXXXXXX-391-296.png

引入Beehive後,依賴關系會把幾條紅線全部引向Beehive模塊,而Beehive模塊則是獨立於各層之外的。

33.png

Beehive的原理是,每一個對外提供服務的模塊,需要注冊一個抽象接口到Beehive提供的Interfaces(接口池)。注意,在這個池子裡只有抽象接口。

開發階段,調用方依賴接口池中響應的接口,並以接口為參數,通過Beehive提供的工廠方法獲取一個服務實例,這個實例可以正常進行服務。

運行時階段,Beehive工廠方法根據服務的注冊配置,構造服務實例。若:當前的運行環境沒有依賴提供服務的模塊,則返回空;若:當前運行環境依賴關系完整,則開始構造服務,並返回。

34.png

通過這樣的方案,就可以實現模塊間解耦。

  • 統跳協議 & Rewrite引擎

統調協議是一個基於URL的跳轉方案,配合Rewrite引擎實現全App調用解耦。此前蘋果核有一篇文章詳細介紹,這裡我就不詳述細節。

  • Beehive和統跳&Rewrite的區別

Beehive和統跳協議的目的都是解耦,然後二者所關注的重心不同。統跳主要為界面解耦服務,業務要求界面鏈路的強動態性;Beehive則為模塊解耦,解決模塊強依賴帶來的開發階段痛苦。

以上,就是我們在過去的幾年裡,整個手機天貓所經歷的解耦過程。在這個過程裡,我們有過很多思考,也踩了很多坑,當然也沉澱了很多好用的工具。希望接下來能有更多機會跟各位分享,也歡迎各位跟我們交流,互相學習。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved