网友zhanglPeng在我一篇博客评论区邀请我写一篇BeeHive原理解析,我答应了他,刚好周末有一点点时间,于是抽空看了下BeeHive源码写下这篇文章。如有见解不到之处敬请提出指正。
BeeHive
BeeHive是一款阿里开源应用于iOS工程模块化编程框架。吸收了Spring框架 Service的理念来实现模块间的API耦合,原理即是向Mediator注册Protocol和相应的Impl.
大家来找茬
仔细瞅了下代码发现两处明显命名错误
第一处
[[BHModuleManager sharedManager] tiggerEvent:BHMSetupEvent];
tigger
?应该是trigger
吧。
第二处
[BeeHive shareInstance].enableExpection = YES;
这行代码作用是让开发者设置是否允许BeeHive抛出异常,仔细看Expection(期望)。。。正确的应该是exception
暂时只发现2处,欢迎大家有兴趣下载源码来找茬。
框架结构
– BHContext
APP上下文对象,记录APP的API环境等信息。为了方便让其他开发者扩展配置,BHContext
持有了一个BHConfig
,开发者可以利用BHConfig
提供的API 配置自定义扩展信息,如下图
@interface BHConfig : NSObject
+(instancetype) shareInstance;
+(id)get:(NSString *)key;
+(BOOL)has:(NSString *)key;
+(void) add:(NSDictionary *)parameters;
+(NSMutableDictionary *) getAll;
+(NSString *)stringValue:(NSString *)key;
+(NSDictionary *)dictionaryValue:(NSString *)key;
+(NSInteger)integerValue:(NSString *)key;
+(float)floatValue:(NSString *)key;
......
有一个疑问,BHContext
持有了一个BHConfig
对象,但是BHConfig
类中提供的均是类方法,我仔细瞄了好几眼,一个实例方法都没有,但是BHContext
持有了一个BHConfig
的实例对象,我猜测可能是留着以后扩展的。
通过这种方式扩展配置信息会导致一定量的HardCode,带来维护和使用上的不便。实际效果远不如BHConfig
中挂一个property看的直观,而且可能一些公司的应用环境超过了BHEnvironmentType
枚举中列出的环境,也不太方便拓展。
– BHModuleManager
模块管理器。启动时需要被BHModuleManager
管理的Module
都会被注册,且缓存了所有被注册Module
的实例对象.
注册方式:
########一.动态注册
需要被动态注册的Module
,在该Module
的实现文件.m中,复制宏BeeHiveMod(ShopModule)
,(具体原理我只了解了七七八八就不做过多解释了,想了解的同学可以去查询资料..)
在BHModuleManager
中- (void)registedAnnotationModules
方法内,由BHAnnotation
调用内部的static NSArray<NSString *>* BHReadConfiguration(char *section)
方法获取到内存中以宏定义中特殊命名的数据,转换成Module
的ClassName,再通过runtime构建相应的Module
实例对象进行缓存.
########二.加载local pilst
把需要注册的Module
配置在相应的plist文件中,也可以配置Module
的level,启动时加载plist文件,读取存储了Module
的ClassName的list,通过runtime的反射构建需要注册的Module
实例对象进而缓存
########三.主动注册
在需要注册的Module
的+ (void)load
方法中调用[BeeHive registerDynamicModule:[self class]];
主动注册
以上注册方式任意选择一种,我建议在项目中统一用一种注册方式.
BHModuleManager
中缓存了所有被注册Module
的一份实例,但是他不对外提供获取Module
的接口,所以我认为凡是遵守BHModuleProtocol
协议的Module
做的事情仅限于处理系统事件和一些应用事件。他并非我们理解的普通的业务Module
。
Module
不能在外部alloc 出来,因为你即使创建一个新的Module
实例出来,你并不在BHModuleManager
的管理下,是无法接收BHModuleManager
分发的系统事件,创建出来没有意义。
– BHServiceManager
和BHModuleManager
一样提供了3种注册方式,不过只能用其中一种方式注册,如果同时用2种方式注册会抛出异常。
BHServiceManager
对外提供了根据protocol获取到相应的Impl实例(原理和我第一篇组件化总结-protocol注册方案一样),这是BeeHive
最核心的功能。
– BHServiceProtocol
没什么可讲的,就2个接口
-(BOOL)singleton;
+(id)shareInstance;
– BHModuleProtocol
定义的Module
生命周期回调接口,以及系统事件接口。BHServiceManager
会在接收到系统事件后,分发给所有在他内部管理的并且实现BHModuleProtocol
相应接口的Module
– BeeHive
对外的入口模块,采用了外观设计模式,BHServiceManager
和BHModuleManager
2个类没有对外暴露,由BeeHive
对外提供相应的接口,BeeHive
内部调用BHServiceManager
和BHModuleManager
相应的接口.
Beehive虽然有瑕疵,但是有一些设计思路还是很值得学习借鉴。希望Beehive会越来越好!