组件化工具BeeHive(一):事件分发

BeeHive是阿里开源的组件化框架,通过事件分发和protocol-class方案实现模块解耦。事件分发包括直接调用和BeeHive分发两种方式,后者能减少模块间的耦合。注册Module有四种方式,包括动态注册、宏定义、使用BeeHiveMod宏和plist文件。BeeHive内部通过BHModuleManager进行事件分发,根据事件类型找到相应Module的响应方法执行。
摘要由CSDN通过智能技术生成

前言

BeeHive是阿里开源的一个组件化框架工具,其内部是使用Spring框架Service的理念来实现模块解耦的,实际上就是使用protocol-class的方案。另外,在组件化的基础上,BeeHive还增加了一个事件分发的功能来配合使用。

1. 概览

官方文档中的架构图:

请添加图片描述

从上图可以看出,BeeHive的工作分为两部分:

事件分发
BeeHive本身会监听一些系统事件和应用事件,比如App生命周期、推送、handoff等,当事件发生时,BeeHive将其分发给各个模块,然后各个业务模块就可以在自己的Module类中调用各自的响应方法。

组件化
这部分是指在组件化的情况下,实现模块间调用,也就是说,各个模块是相互解耦的,BeeHive使用protocol-class的方案实现这一点。

2. 事件分发的作用

当一个事件被触发时,其对应的响应方法需要被执行,比如界面更新、数据存储等。在这个过程中,会涉及到响应方法的调用和实现这两部分。

首先需要确定的是响应方法的实现都是由模块来完成的(不属于现有模块的响应方法可以看做是属于一个全局模块),针对调用响应方法的位置,这里就有两种调用方式,一个是直接在事件触发点调用(通常是在AppDelegate),另一个是通过BeeHive将事件分发给各个模块,在具体模块的Module类中调用。
为了对比这两种调用方法的差别,下面以一个例子来说明:

一个场景

用户在spotlight搜索一个关键字testA,点击搜索结果,app需要跳转到模块A中的一个界面;
搜索关键字testB,点击搜索结果,app需要跳到模块B中的一个界面。

在这个场景中,当用户在spotlight中点击一个搜索结果后,会触发一个handoff事件,这个事件会被AppDelegate接受到,可以把AppDelegate当做是事件的触发点。 这个事件期望的响应是,根据点击的搜索结果,跳转到对应的模块界面中。

2.1. 直接调用

直接调用事件的响应方法,代码如下:

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{
   
    
    if ([userActivity.activityType isEqualToString:@"com.company.app.moduleA.one"]) {
   
        
        id<ModuleAServiceProtocol> moduleAService = [[BeeHive shareInstance] createService:@protocol(ModuleAServiceProtocol)];
        [moduleAService pushToModuleAOneViewController];
        
    }else if ([userActivity.activityType isEqualToString:@"com.company.app.moduleB.one"]) {
   
        
        id<ModuleBServiceProtocol> moduleBService = [[BeeHive shareInstance] createService:@protocol(ModuleBServiceProtocol)];
        [moduleBService pushToModuleBOneViewController];
        
    }
    return YES;
}

上述代码中BeeHive的createService:方法是用来获取对应的模块句柄(下文会具体讲到),使用这个句柄可以直接调用模块的响应方法,跳转到模块对应的界面。
根据userActivity的类型来判断app是跳转到moduleA的界面还是moduleB的界面。

直接调用存在的问题

  • 在事件触发点处(AppDelegate)直接调用模块的响应方法,会将事件的响应代码全都堆积在触发点处,当事件的类别越来越多,这个地方会存在许多判断语句,不便于阅读和维护;
  • 更重要的是会导致触发点对各个模块产生依赖,继而会影响触发点的稳定性,只要模块稍有改动,触发点也要跟着变动。
  • 在执行事件的响应方法的过程中,会涉及到响应方法的调用逻辑和实现逻辑这两部分。响应方法的实现逻辑通常是在模块中完成的,采用第一种方式
  • 响应方法的调用逻辑会在触发点处完成,整个事件的处理过程会被分割在触发点和模块这两部分中,当需要对事件的响应逻辑做出变动时,则需要在这两部分同时做出改变。
  • 事件触发点一般是位在主工程中,在大型项目中,模块和主工程一般是分开开发的,并且可能是由不同的开发者开发的,一个事件最好不要同时涉及到这两部分,因为这样会导致这两部分存在某种耦合,不易于维护。

2.2. 事件分发

在使用BeeHive之后,BeeHive会监听这些事件,事件触发后,它会遍历已注册模块对应的Module类,然后调用这些类对应的事件响应方法,这样,BeeHive就将一个事件分发给了所有的Module类。
换句话说,就是给每一个需要响应事件的模块都新建一个对应的Module类,在这个Module类中完成对响应方法的调用,这个Module类和模块将由同一个开发者创建和维护。
这样,一个事件的整个响应过程就都是由模块负责,主工程只需要负责事件分发。事件的处理被隔离在模块内部,即便以后需要修改事件的响应逻辑,也只需要改动模块,主工程不需要任何改动。

3. 事件分发的配置过程

3.1. 初始化

BeeHive内部有一个类BHAppDelegate,它的作用就是监听事件的触发,实际项目中的AppDelegate需要继承这个类。

//AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   
    
    [BHContext shareInstance].application = application;
    [BHContext shareInstance].launchOptions = launchOptions;
    [BHContext shareInstance].moduleConfigName = @"BeeHive.bundle/BeeHive";
    [BHContext shareInstance].serviceConfigName = @"BeeHive.bundle/BHService";
    
    [BeeHive shareInstance].enableException = YES;
    [[BeeHive shareInstance] setContext:[BHContext shareInstance]];
    
    [super application:application didFinishLaunc
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值