BeeHive,一次iOS模塊化解耦實踐


1.爲何須要BeeHive?

在天貓App的快速發展過程當中,人員不斷壯大,業務不斷複雜,代碼量隨之增多,帶來的是協做開發中遇到各類各樣的問題。html

你是否曾在這樣的環境下艱難開發?畏手畏腳地邊作需求邊改BUG。java

develop
develop

同時iOS的工程代碼的耦合多是這樣的:ios

arch
arch

AppDelegate中包含大量庫的init以及其餘操做,少則幾百行,多則上千行,無關代碼堆積在其中,維護成本極高,不一樣庫的調用邏輯互相交錯,以下圖所示:git

arch
arch

麪條式的耦合,致使上層業務受限於底層基礎庫的依賴影響,BUG排查緩慢、新功能增長效率隨代碼量遞增而不斷遞減。github

1.1 開發中主要問題

開發過程當中總結了如下App開發中遇到的問題:spring

  • 功能代碼之間的依賴複雜,可維護性差
  • 協同開發過程當中,並行開發存在block狀況
  • 功能界限不清晰,基礎功能模塊變更,會致使上層業務受到影響
  • 各團隊負責功能模塊,在主工程中有耦合代碼
  • 上層業務會出現反向提供功能給底層狀況
  • 性能分析優化,隨代碼增長變得困難

1.2 App和開發人員的訴求

一個App應該有以下特性:apache

  • 功能可維護性
  • 功能可用性
  • 功能具備良好性能
  • 功能可分析,可量化
  • 功能可單元測試

開發人員但願協同開發中可以作到如下幾點:編程

  • 不但願被別人block住開發
  • 依賴庫版本、約定的接口要穩定
  • 以最少侵入式代碼來接入某個功能

代碼隔離開發問題,經過Cocoapods獲得解決,代碼層面達到了分割,但邏輯功能上的耦合問題仍是沒法解決。開發人員但願在擴展業務的同時作到快速穩定,所以須要有一種App模塊解耦方式來讓開發人員中免受依賴關係的痛苦,因而讓開發人員產生了打造一個BeeHive全局基礎框架的想法。性能優化

2. BeeHive的最佳實踐

BeeHive的使用方法能夠參考BeeHive的README。這裏舉一個實際開發中的例子。bash

2.1 3D-Touch例子

2.1.1 場景1:搭建3DTouch場景

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 
}
複製代碼

2.1.2 場景2:3DTouch須要動態化,可量化

一個動態配置quickAction需求的到來,以往的作法須要引入配置Module,建立對應一系列調用流程,這時只須要調用配置Service便可,並且但願更早的更新quickActionItem,因而能夠調用modInit來實現。

-(void)modQuickAction:(BHContext *)context
{
  ....
  //update config by configCenter Service 
}
複製代碼

產品方還但願知道用戶都用了哪些QuickAction,這時調用UserTrack Service便可,諸如此類的一個上層業務,開發人員要調用Log,Cache等等服務,採用BeeHive Service形式後只需一行調用便可。

2.1.3 場景3:3DTouch須要作到個性化

在沒有服務端的狀況下,如何作到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幾大功能點:

  • Module的建立,感知App生命週期
  • 對內引入、調用Service
  • 對外提供Service
  • 功能移植,無需copy,podfile中增長pod源

整個3DTouch開發過程當中不涉及其餘其餘功能的具體實現,面向切片編程過程當中,只要關心本身模塊對應的需求便可。

3. BeeHive結構與原理解析

BeeHive借鑑了Spring Service、Apache DSO的架構理念,採用AOP+擴展App生命週期API形式,將業務功能、基礎功能模塊以模塊方式以解決大型應用中的複雜問題,並讓模塊之間以Service形式調用,將複雜問題切分,以AOP方式模塊化服務,舉例來講日誌、埋點模塊採用AOP方式後,業務方不須要考慮日誌、埋點的相關代碼,只要以createService去聲明調用Service便可。

相應的BeeHive架構以下:

architecture
architecture

Core + plugin的形式可讓一個應用主流程部分獲得集中管理,不一樣模塊以plugin形式存在,便於橫向的擴展和移植。

圖中的BHContext,是BeeHive的配置文件,提供全局統一上下文信息。
圖中的BHCore即BeeHive提供註冊、建立Module、Service邏輯,Module、Service註冊和調用邏輯只和核心模塊相關,Module之間沒有直接的關聯關係。

BeeHive核心思想涉及兩個部分:

  1. 各個模塊間調用從直接調用對應模塊,變成調用Service的形式,避免了直接依賴。
  2. App生命週期的分發,將耦合在AppDelegate中邏輯拆分,每一個模塊以微應用的形式獨立存在。

BeeHive提供了三種不一樣的調用形式,靜態plist,動態註冊,annotation。Module、Service之間沒有關聯,每一個業務模塊能夠單獨實現Module或者Service的功能。

3.1 Module

module
module

圖中包含了主要的BeeHive啓動過程以及Module的時序邏輯。Module的事件分發源於BHAppDelegate中的triggerEvent,對應GlobalContext也在回調中提供給業務方。

BHAppDelegate中除了回調系統的事件,還將App生命週期進行擴展,增長ModuleSetup,ModuleInit,ModuleSplash,此外開發人員還能夠自行擴展。


�service
�service

擴展週期過程當中,同時加入Module分析量化功能,每一個模塊Init的耗時都可計算出來,爲性能優化作到數據上的支持。一個App的業務增多過程當中,經過分析定位Module的Init耗時能夠肯定須要優化的Module。

Module遵循BHModuleProtocol後,可以捕獲App狀態的回調,並擁有App生命週期內的全局上下文,經過context可獲取配置參數,模塊資源以及服務資源。
以BeeHive做爲底層框架的App,除了解耦帶來的便利,開發人員在開發新App過程當中涉及相同功能的Module,無需重複造輪子,直接移植Module,開發一個App如同拼裝積木,能組合須要的功能業務。

3.2 Service

�service
�service

上述圖中包含Service相關的邏輯,業務A能夠經過createService直接調用服務,Module根據需求動態註冊某個服務。Service的調用和實現,核心是BHServiceManager。能夠單首創建Services interface Pod,統一放置要用的Services,這樣的業務依賴就從網狀式變成中心式,業務方只需依賴Services一個。

Service能夠動態共享對象,按需加載,BeeHive邏輯是將基礎服務註冊在plist中,業務型服務容許Service不先註冊,直到業務須要時才被動態註冊。

Service支持兩種不一樣模式:

  • 單例: 對於全局統一且無狀態服務,建議使用這種建立形式,這樣有利於Service的統一管理以及減小沒必要要內存消耗。
  • 多實例: 每次調用服務都從新建立新的服務,對於涉及狀態以及狀態變化的服務最適合使用多實例方式。

在多線程環境下遇到了Service讀寫問題,已經過Lock來已避免Array crash問題。

不過Service還存在以下問題:

  • Service依賴關係,致使底層依賴的Service沒有被建立時就被調用。
  • 規劃Service、Module建立順序,使得App達到秒開,優化性能體驗。

前者依賴問題計劃經過調度機制來解決,後者還須要將AppDelegate更多業務剝離以及實踐纔可,這裏不細談。

4. BeeHive背後的思考

BeeHive以一個分發App狀態和統一Service Interface的架構形式解決了多團隊多開發人員協同開發中的耦合問題。對於實踐過程當中的開發成本,適應須要必定過程,但邏輯理順後,應用起來不成問題。就收益而言,BeeHive更適合大型的多人項目以及快速移植的項目,小項目使用起來較複雜,有些得不償失。

至此,BeeHive中主體已分析到位,BeeHive是一個正在成長的iOS框架,目前Star已1500+,但願你們能夠集思廣益,多提issue、Pull Request,這樣BeeHive也能讓更多人受用。想象一下像蜜蜂同樣優雅地搭建每一個蜂窩模塊。


�service
�service

5. 參考

  1. Spring相關資料
  2. Apache DSO參考連接
  3. Cocoapods資料

>做爲一個開發者,有一個學習的氛圍和一個交流圈子特別重要,這是個人交流羣,你們有興趣能夠進羣裏一塊兒交流學習761407670(123)


原文做者:戴鵬

地址:https://www.infoq.cn/article/beehive-a-ios-modular-decoupling-practice/

相關文章
相關標籤/搜索