天天看點

iOS大型項目解耦方案有難度?BeeHive設計優化來幫助背景BeeHive實踐之路BeeHive的展望與問題

在2017年線上技術峰會——阿裡開源項目最佳實踐上,來自天貓的戴鵬帶來了beehive關于ios大型項目解耦方案的分享。他從多人開發的問題介紹了業界的三種子產品方案,将傳統init與beehive module進行了比較,對beehive的架構進行了分析,并對module manager和module的實作進行了詳細介紹。

以下内容根據直播視訊整理而成。

在ios大型項目中如何抽絲剝繭把對應的需要優化的地方進行優化、多人協作開發中如何避免沖突?本文為你詳細解答。

<b></b>

iOS大型項目解耦方案有難度?BeeHive設計優化來幫助背景BeeHive實踐之路BeeHive的展望與問題

2015年上半年,開始參與天貓ipad開發,負責的主要内容包括我的天貓以及首頁一些程式架構性的東西。2015年下半年之後,開始參與天貓iphone開發,主要負責直播項目。

在多人開發模式中涉及到了溝通交流以及互相合作的問題。在代碼依賴層面,功能調用比較繁瑣,功能之間互相依賴,底層功能反向依賴上層業務。在協同開發層面,合并沖突,費時費力,合作開發、接口不穩定,頻繁更新接口。在量化分析層面,代碼耦合難以分析性能、難以做單元測試。在性能優化層面,每個庫侵入app生命周期,難區分庫初始化必要性,導緻啟動卡頓。

惡劣的開發環境像面條式的邏輯文化。老練的開發人員也會畏手畏腳,因為整個疊代周期流程中包含了開發過程以及修bug過程,如果在一個耦合嚴重的情況下做這些操作的話,可能造成更多bug的引入。整個工程如果沒有做到合理的分類的話,其實業務和基礎邏輯就會交織纏繞在一起,可維護性降低。

在開發過程中,為了支援業務的快速發展,并沒有認真思考整個應用該具備哪些特點。而所有的應用必須具備以下三個特點:<b>維護性</b>,支援多人持續開發;<b>可用性</b>,有良好性能及功能完備;<b>可分析性</b>,支援優化、使用者行為分析。

iOS大型項目解耦方案有難度?BeeHive設計優化來幫助背景BeeHive實踐之路BeeHive的展望與問題

url router可以參考開源界比較成熟的方案jr route,把每一個子產品以一個url的形式作為獨立存在的界限範圍。url router需要在記憶體中維護一張url表作為key來實作對應的push或者喚起對應的子產品。它在傳遞參數過程中不能傳遞類似于對象這樣的資料,隻能傳遞string這類的資料。

target action也是基于蘋果原生的runtime的優勢,其優勢很大在于可以做到無需加載記憶體,并且在調用中沒有相關的依賴。在調用中的缺陷在于隻有在運作池中才可以知道對應的元件是否存在,若不存在會造成對應的crash。

protocol class是利用原始class以及對應的protocol用到的service interface去進行實作以及接口的分離,讓大部分的業務方隻需要基于protocol的interface進行調用。其過程中會涉及到記憶體占用的問題。

iOS大型項目解耦方案有難度?BeeHive設計優化來幫助背景BeeHive實踐之路BeeHive的展望與問題

beehive相當于一個蜂巢,我們希望每個子產品都像六角形的蜂窩可以獨立存在,可以同時對外有很好的接口。

iOS大型項目解耦方案有難度?BeeHive設計優化來幫助背景BeeHive實踐之路BeeHive的展望與問題

ios分層有幾種層次:核心的core os層、其上的core services和media layer、cocoa touch對于開發者人員來說是比較黑盒的東西。而一個個獨立的app也類似于插件的形式插在系統當中。最上層的應用生命周期是管控平台。

iOS大型項目解耦方案有難度?BeeHive設計優化來幫助背景BeeHive實踐之路BeeHive的展望與問題

傳統的init有三個層次,此過程中init沒法做到很好的區分,并且其中有些比較耗時的操作是沒有必要的。對應的beehive module是把一個個module進行了細粒度的拆分,通過module manager的形式将整個應用的生命周期進行了發放,每個module在自己的回調過程中隻需要遵循module protocol就可以感應到整個應用的生命周期,在不同場景下做對應的程式響應。

iOS大型項目解耦方案有難度?BeeHive設計優化來幫助背景BeeHive實踐之路BeeHive的展望與問題

module manager除了拆分應用的生命周期還擴充了生命周期。從上下圖對比當中我們可以知道,beehive中加了三塊流程,modulesetup、moduleinit、modulesplash,這三個流程對于大部分子產品的初始化來說已經足夠用了。在這個過程中,還支援了自定義的moduleevent,可以在任意一個app的生命環節中做到插入式的回調,這些回調便于在某些場景中展示某項業務功能的定制化内容。

module存在的意義在于:拆解主工程中耦合;分發狀态;定義app狀态;量化分析子產品耗時;支撐橫向擴充能力。

iOS大型項目解耦方案有難度?BeeHive設計優化來幫助背景BeeHive實踐之路BeeHive的展望與問題

在modulesetup和moduleinit時,都對module的耗時進行了記錄。module monitor做到了記錄耗時、check主線程占用、記錄對應子產品加載的順序過程。module monitor也是作為插件植入到了beehive中。

iOS大型項目解耦方案有難度?BeeHive設計優化來幫助背景BeeHive實踐之路BeeHive的展望與問題

從beehive裡面的工程可以看出來module交易子產品、使用者買點、業務home、shop的加載情況。這些資料都可以為之後的性能優化做支撐。

iOS大型項目解耦方案有難度?BeeHive設計優化來幫助背景BeeHive實踐之路BeeHive的展望與問題

在beehive core裡,每一個module的業務排程都是以一個插件的形式存在。module的注冊、service的注冊,beehive提供幾種形式:寫在plist裡,注解,動态調用。而context裡面主要包含了一些全局性的内容,比如服務端傳回的整個app環境,config裡面也存儲了全局可讀的狀态便于整個子產品共享資源。

iOS大型項目解耦方案有難度?BeeHive設計優化來幫助背景BeeHive實踐之路BeeHive的展望與問題

上圖中三個不同的業務在調用過程中涉及到了4個基礎庫的子產品。可以看出,其中很多的關聯關系是沒有必要存在的,比如日志庫到網絡庫、網絡庫到日志庫隻需要單點的依賴就可以了。

iOS大型項目解耦方案有難度?BeeHive設計優化來幫助背景BeeHive實踐之路BeeHive的展望與問題

beehive對service module進行了一個處理,service manager主要了service protocol的實作,比如管理了單例或者多例的情況。所有的業務不再直接依賴各種庫,而是通過interface的形式,業務就以一個切片的形式隻需要關心業務的流程,大大提升了工作效率。

iOS大型項目解耦方案有難度?BeeHive設計優化來幫助背景BeeHive實踐之路BeeHive的展望與問題

如上圖所示,service阻隔子產品間依賴是以一個中心化的方式把原本無序化面條式的業務耦合變成了新形式的耦合。service存在這樣的特性:service吸收了spring service的開發理念,以一種aop的形式存在;register和module一樣存在着三種模式,靜态注冊、代碼注冊、注解注冊;是否單例和多例也和spring service保持一緻。

iOS大型項目解耦方案有難度?BeeHive設計優化來幫助背景BeeHive實踐之路BeeHive的展望與問題

在大工程的開發過程中,會遇到xcode跑的很慢的情況,也許隻是改變了幾個小的檔案,但是這些檔案在編譯、打包的過程中耗時還是比較嚴重的。一方面可以買新的電腦來提升編譯速度,或者多開幾個xcode線程達到提升性能的目的。protocol-class可以通過三方面來提升編譯的速度:配置設定、分離接口和實作,通過protocol分割在不同的子產品來做代碼間直接依賴的隔斷;service實作合并編譯也可提升相應速度,因為單獨一個子產品當中提供的一些service可以合并到大的整個的module service中,更少的檔案也就提高了編譯效率;業務引入更少頭檔案對編譯速度也有一定的提升。

iOS大型項目解耦方案有難度?BeeHive設計優化來幫助背景BeeHive實踐之路BeeHive的展望與問題

非beehive環境下開發3dtouch功能的步驟如上圖所示。各種需求帶來子產品的引用。首先,動态化需要引入相關的配置内容,前背景切換以及個性化quick action涉及到本地存儲,更進一步的個性化用到了使用者埋點相關的東西。對外由于需要記錄各種資料,在沒有服務端的配合下需要對外提供一些service。

iOS大型項目解耦方案有難度?BeeHive設計優化來幫助背景BeeHive實踐之路BeeHive的展望與問題

在beehive環境下開發這樣功能需要關注的點很少,不需要引入這樣那樣的子產品,隻需要引入一個module關注它希望在整個生命周期中想要知道的内容。對應期待的服務隻要依賴對應的service interface就行。對外提供的service也是以beehive的service manager作為中轉。

每一個都是獨立子產品,又享有了全局的context、service interface,對橫向擴充具有插件式的開發。引入新的業務會非常獨立,沒有耦合的情況。對于移植來說,隻要以一個module形式存在并且新的工程當中也是以beehive作為基礎的話,可以做到即拿即用。

支援app秒開的智能排程邏輯,對于module的加載分析還是以單純的記錄,不能做到智能加載的過程。需要支援更多的service調用形式。service依賴以及排程邏輯也存在一些問題。

beehive的架構帶來了一定的學習成本,隻有在一定複雜的情況下,beehive的價值才能夠展現出來。複雜度守恒原理也提到,将業務間的耦合剝離開來會造成beehive内部的複雜,通過了一些線程的保護避免了一些快速的情況。beehive希望以一個基礎庫的形式管理整個應用的周期以及對應的外部插件。

繼續閱讀