美文网首页iOS程序犭袁iOSiOS开发
BeeHive-阿里开源iOS模块解耦框架源码解析

BeeHive-阿里开源iOS模块解耦框架源码解析

作者: sun6boys | 来源:发表于2017-01-21 19:48 被阅读2532次

    网友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)方法获取到内存中以宏定义中特殊命名的数据,转换成ModuleClassName,再通过runtime构建相应的Module实例对象进行缓存.

    ########二.加载local pilst
    把需要注册的Module配置在相应的plist文件中,也可以配置Module的level,启动时加载plist文件,读取存储了ModuleClassName的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

    对外的入口模块,采用了外观设计模式,BHServiceManagerBHModuleManager2个类没有对外暴露,由BeeHive对外提供相应的接口,BeeHive内部调用BHServiceManagerBHModuleManager相应的接口.

    Beehive虽然有瑕疵,但是有一些设计思路还是很值得学习借鉴。希望Beehive会越来越好!

    相关文章

      网友评论

      • Saber丨断了弦的吉他丨iO:大龙越来越像样了:grin:
      • keshiim:哈哈,,,,阿里开源。。里开源。。开源。。源。。
        sun6boys:@也许wol 客气了,有帮助就好。他们已经修复了我提出的一些问题了:smile:
        也许wol:感谢分享:blush: 公司里的项目目前正在重构,引入了BeeHive框架,这篇文章很有帮助:smile:
        sun6boys:@keshiim :smile:
      • _帥気崪:注册protocol的方式进行模块相互调用不是应该拿到实现protocol的对象,在通过这个对象调用相应的方法么,为什么这个框架 “[BeeHive shareInstance] createService:@protocol”后获得的都是controller
        sun6boys:@_帥気崪 模块也不一定是controller,你不也说了么,这是个demo
      • o0下一站生活0o:
        #define BeehiveServiceSectName "BeehiveServices"
        大神能不能讲讲这个动态注册,没看懂怎么注册的。
        sun6boys:@molon 谢谢。
        24cad160dfd0:@o0下一站生活0o 一般编译后的文件会打包有字符串常量区,这个就是自己命名一个区域名称,把一些字符串塞到里面,可以简单理解为一个程序二进制文件内的存储方式,但其在编译时候就已经决定了内容。具体关于文件结构可以通过MachOView查看。
      • 贝壳绿源:顶一个

      本文标题:BeeHive-阿里开源iOS模块解耦框架源码解析

      本文链接:https://www.haomeiwen.com/subject/jkrnbttx.html