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