在天貓App的快速發展過程當中,人員不斷壯大,業務不斷複雜,代碼量隨之增多,帶來的是協做開發中遇到各類各樣的問題。html
你是否曾在這樣的環境下艱難開發?畏手畏腳地邊作需求邊改BUG。java
同時iOS的工程代碼的耦合多是這樣的:ios
AppDelegate中包含大量庫的init以及其餘操做,少則幾百行,多則上千行,無關代碼堆積在其中,維護成本極高,不一樣庫的調用邏輯互相交錯,以下圖所示:git
麪條式的耦合,致使上層業務受限於底層基礎庫的依賴影響,BUG排查緩慢、新功能增長效率隨代碼量遞增而不斷遞減。github
開發過程當中總結了如下App開發中遇到的問題:spring
一個App應該有以下特性:apache
開發人員但願協同開發中可以作到如下幾點:編程
代碼隔離開發問題,經過Cocoapods獲得解決,代碼層面達到了分割,但邏輯功能上的耦合問題仍是沒法解決。開發人員但願在擴展業務的同時作到快速穩定,所以須要有一種App模塊解耦方式來讓開發人員中免受依賴關係的痛苦,因而讓開發人員產生了打造一個BeeHive全局基礎框架的想法。性能優化
BeeHive的使用方法能夠參考BeeHive的README。這裏舉一個實際開發中的例子。bash
iPhone 6s及以上的設備支持3D-Touch後,幾乎全部應用都在適配其特性,按照慣例,在AppDelegate中包含以下代碼:
-(void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler
{
....
}
複製代碼
這意味着AppDelegate要增加代碼行數,實則QuickAction的功能沒有必要寫在AppDelegate中。利用BeeHive框架特性,建立3DTouch Pod,獨立3DTouch相關業務功能。
-(void)modQuickAction:(BHContext *)context
{
....
//process context.shortcutItem
}
複製代碼
一個動態配置quickAction需求的到來,以往的作法須要引入配置Module,建立對應一系列調用流程,這時只須要調用配置Service便可,並且但願更早的更新quickActionItem,因而能夠調用modInit來實現。
-(void)modQuickAction:(BHContext *)context
{
....
//update config by configCenter Service
}
複製代碼
產品方還但願知道用戶都用了哪些QuickAction,這時調用UserTrack Service便可,諸如此類的一個上層業務,開發人員要調用Log,Cache等等服務,採用BeeHive Service形式後只需一行調用便可。
在沒有服務端的狀況下,如何作到QuickAction個性化,註冊並提供了3DTouchBHService,給其餘業務調用好比某個功能頁面
-(void)updateAccessTimesWithActionURL:(NSURL *)actionURL
{
....
// save view controller access times by cache service
// update local quickAction Items by access times and any other element
}
複製代碼
上面三個典型場景主要涉及的到BeeHive幾大功能點:
整個3DTouch開發過程當中不涉及其餘其餘功能的具體實現,面向切片編程過程當中,只要關心本身模塊對應的需求便可。
BeeHive借鑑了Spring Service、Apache DSO的架構理念,採用AOP+擴展App生命週期API形式,將業務功能、基礎功能模塊以模塊方式以解決大型應用中的複雜問題,並讓模塊之間以Service形式調用,將複雜問題切分,以AOP方式模塊化服務,舉例來講日誌、埋點模塊採用AOP方式後,業務方不須要考慮日誌、埋點的相關代碼,只要以createService去聲明調用Service便可。
相應的BeeHive架構以下:
Core + plugin的形式可讓一個應用主流程部分獲得集中管理,不一樣模塊以plugin形式存在,便於橫向的擴展和移植。
圖中的BHContext,是BeeHive的配置文件,提供全局統一上下文信息。
圖中的BHCore即BeeHive提供註冊、建立Module、Service邏輯,Module、Service註冊和調用邏輯只和核心模塊相關,Module之間沒有直接的關聯關係。
BeeHive核心思想涉及兩個部分:
BeeHive提供了三種不一樣的調用形式,靜態plist,動態註冊,annotation。Module、Service之間沒有關聯,每一個業務模塊能夠單獨實現Module或者Service的功能。
圖中包含了主要的BeeHive啓動過程以及Module的時序邏輯。Module的事件分發源於BHAppDelegate中的triggerEvent,對應GlobalContext也在回調中提供給業務方。
BHAppDelegate中除了回調系統的事件,還將App生命週期進行擴展,增長ModuleSetup,ModuleInit,ModuleSplash,此外開發人員還能夠自行擴展。
擴展週期過程當中,同時加入Module分析量化功能,每一個模塊Init的耗時都可計算出來,爲性能優化作到數據上的支持。一個App的業務增多過程當中,經過分析定位Module的Init耗時能夠肯定須要優化的Module。
Module遵循BHModuleProtocol後,可以捕獲App狀態的回調,並擁有App生命週期內的全局上下文,經過context可獲取配置參數,模塊資源以及服務資源。
以BeeHive做爲底層框架的App,除了解耦帶來的便利,開發人員在開發新App過程當中涉及相同功能的Module,無需重複造輪子,直接移植Module,開發一個App如同拼裝積木,能組合須要的功能業務。
上述圖中包含Service相關的邏輯,業務A能夠經過createService直接調用服務,Module根據需求動態註冊某個服務。Service的調用和實現,核心是BHServiceManager。能夠單首創建Services interface Pod,統一放置要用的Services,這樣的業務依賴就從網狀式變成中心式,業務方只需依賴Services一個。
Service能夠動態共享對象,按需加載,BeeHive邏輯是將基礎服務註冊在plist中,業務型服務容許Service不先註冊,直到業務須要時才被動態註冊。
Service支持兩種不一樣模式:
在多線程環境下遇到了Service讀寫問題,已經過Lock來已避免Array crash問題。
不過Service還存在以下問題:
前者依賴問題計劃經過調度機制來解決,後者還須要將AppDelegate更多業務剝離以及實踐纔可,這裏不細談。
BeeHive以一個分發App狀態和統一Service Interface的架構形式解決了多團隊多開發人員協同開發中的耦合問題。對於實踐過程當中的開發成本,適應須要必定過程,但邏輯理順後,應用起來不成問題。就收益而言,BeeHive更適合大型的多人項目以及快速移植的項目,小項目使用起來較複雜,有些得不償失。
至此,BeeHive中主體已分析到位,BeeHive是一個正在成長的iOS框架,目前Star已1500+,但願你們能夠集思廣益,多提issue、Pull Request,這樣BeeHive也能讓更多人受用。想象一下像蜜蜂同樣優雅地搭建每一個蜂窩模塊。
>做爲一個開發者,有一個學習的氛圍和一個交流圈子特別重要,這是個人交流羣,你們有興趣能夠進羣裏一塊兒交流學習761407670(123)
原文做者:戴鵬
地址:https://www.infoq.cn/article/beehive-a-ios-modular-decoupling-practice/