本文是一篇個人學習筆記,記錄以供后續學習參考。
一、項目思路
引用Github中 原文: BeeHive是用于iOS的App模塊化編程的框架實現方案,吸收了Spring框架Service的理念來實現模塊間的API耦合。
二、項目概述
整個項目代碼簡單,結構清晰,優缺點共存,個人不太傾向于目前使用,但是一些思路和做法應該學習。相比其他廠出品的模塊化方案,BeeHive有些稍顯隨意。有另一個名字更適合:“內部模塊解耦框架”。
項目通過兩個集合用以維護模塊化信息,Module集合和Service集合。Module集合中維護每個模塊中Module的class,Service集合維護Service(Protocol)和實現Impl(ViewController)。每個模塊包含Protocol,Module,Impl,Service三層結構,Service可替換Protocol不能算一層獨立結構。
Protocol定義Service提供的行為,對模塊外暴露出來,使用者依賴相關Protocol文件進行調用。模塊內部可能包含多個Service,行為集中到一個或者多個Protocol中,實現使用一個或多個ViewController。
但是模塊內部只有一個Module對象(NSObject),用于接收App生命周期和Module生命周期的回調。同時,通過Module的處理,可以選擇通過動態(Dynamic)方式或注解(Annotation)方式在App啟動時或指定時刻進行注冊。而整體App和Module的生命周期回調,通過AppDelegate繼承,在BHAppDelegate中處理。
缺點:
- 項目的思路感覺有些冗余。
每個Module要提供四類文件:Protocol,Module,Impl(ViewController),Service(介于Protocol和Impl之間)。如果Module本身采用非MVC模式下,單個模塊文件分層更多,不利于理解和管理。 - 代碼內部數據結構有待優化
比如BHServiceManager內部維護了一個數組,數組中的對象是key為Service,value為Impl的字典。與其這樣,為什么不直接使用NSMutableDictionary,key使用Service,實現為Impl呢?檢索的時候減少了手動循環過程。 - 解耦
README中也提到,主旨為Service和Impl解耦但是無法避免對Protocol的解耦。
優點:
- 宏定義實現動態配置
__attribute((used,section("segmentname,sectionname")))
通過宏定義,把變量統一存儲到特殊內存塊中進行一次性讀取比較方便。但是目前沒啥業務場景。 - 生命周期回調
可以做成Protocol實現生命周期回調定義。 - Lock
對于集合類非線程安全,進行加鎖處理,使用NSRecursiveLock。
三、項目結構
BeeHive:
項目對外主入口。通過+registerDynamicModule:動態增加Service,-registerService:(Protocol*) service:(Class)創建Service(Protocol)和Impl(.h+.m)的關聯。通過-createService:創建或獲取Service。
BHServiceManager:
提供了注冊Service和創建(獲取)Service的方法。
一個Service代表一個模塊,Service分為:本地plist中定義的LocalService,通過在.m中宏BeeHiveMod(ShopModule)處理的注解AnnotationService,和在程序運行中主動注冊的Service。
內部維護了一個數組,數組中的對象是key為Service,value為Impl的字典。與其這樣,為什么不直接使用NSMutableDictionary,key使用Service,實現為Impl呢?
BHModuleManager:
提供加載本地Module,注解AnnotationModule和動態DynamicModule的能力。同時是提供生命周期回調的主體。
內部維護了兩個數組分別存儲Module和動態Module及其相應的Level。
BHModuleProtocol:
模塊接口定義,可以設置level,提供了app和module生命周期進行的回調方法。
如果是DynamicModule,整個Module驅動點應該是XXXModule文件,通過宏定義BeeHiveMod被加載,或者在+load方法中注冊成為動態DynamicModule。
BHServiceProtocol:
所有Service Protocol定義必須實現的底層接口。只提供-singleton:方法用于處理是否使用單例模型。
在使用框架時,每個Module中都要有一個XXXProtocol,內部定義用到的實例變量和調用方法。
這樣做有非常明顯的弊端:Module間并未完全解耦,需要依賴ModuleProtocol文件;XXXProtocol中定義的變量要到Impl中@synthesize一下。
BHContext:
上下文對象,提供靜態環境變量初始化和維護,相當于配置中心。
BHConfig:
內部使用可變字典維護動態環境變量,作為BHContext的補充存在。
BHAppDelegate:
作為真正的AppDelegate,使用者的XXXAppDelegate需要繼承,同時自定義-appication:didFinishLaunchingWithOptions:
即可,其他的系統回調交給BHAppDelegate處理。
BHAnnotation:
提供通過注解方式,使用BeeHiveModel和BeeHiveService注冊Module和Service。具體做法是,在Module的.m文件中,添加宏定義BeeHiveMod(ShopModule),在編譯期間替換成
char * kShopModuleName_mod = @“ShopModule”
,并使用__attribute((used,section("segmentname,sectionname")))
把所有包含這段宏轉換后的代碼變量,放到一塊特殊的內存空間中以BeehiveMods命名。同理處理BeehiveServices。然后在BHAnnotation.m中使用c函數直接獲取這部分數據,轉換成NSString進行存儲。