组件化方案

1,131 阅读4分钟

市面上比较常见的三种组件化方案.

  • MGJRouter
  • BeeHive
  • CTMediator

MGJRouter

MGJRouter

url-block的方式, 根据url找到对应的代码块去执行.

注册和调用的简单理解

//注册url
+ (void)registerURLPattern:(NSString *)URLPattern toHandler:(MGJRouterHandler)handler;

MGJRouter的单例有一个NSMutableDictionary类型的routes的属性

例:

[MGJRouter registerURLPattern:@"mgj://foo/bar" toHandler:^(NSDictionary *routerParameters) {
    [self appendLog:@"匹配到了 url,以下是相关信息"];
    [self appendLog:[NSString stringWithFormat:@"routerParameters:%@", routerParameters]];
}];

这样调用了之后,等于是在MGJRouter的单例的routes中添加了如下键值对:

routes = {
    mgj = {
        foo = {
            bar = {
                "_" = "<__NSMallocBlock__: 0x600000d8c6f0>";
            };
        };
    };
}

当我们调用open:url的时候.

+ (void)openURL:(NSString *)URL;

等于是把routes中的_对应的block代码块赋值给了MGJRouterHandler的实例去执行对应的block.

  • 将路由和代码块绑定, 自身模块的调用相对清晰.
  • 参数的传递根据路由模式解析, 可以进行很好的扩展.

  • 硬编码问题, 每个组件的参数调用都需要查找. 蘑菇街为了统一管理自己有一套web页面, 控制url和所有的参数.
  • 所有的urlblock注册在内存中, 组件多了之后会有内存问题.
  • 无法区分本地和远程的调用, 参数的限制可能导致远程功能受限
  • 组件要依赖中间件, 并且分散注册耦合较多.

BeeHive

BeeHive

Protocol-Class的方式, 根据Protocol找到对应的Class进行调用.

  • Class实现Protocol定义的外部接口
  • Protocol暴露出去, 供外部使用. 核心点
  • BHModuleProtocol: Module负责管理模块的注册和释放
  • BHServiceProtocol: 负责组件的开放接口

核心就是单例BHServiceManager负责可变字典allServicesDict属性, 存储了

NSString(协议名): NSString(类名)

取出的时候, 根据协议获取到类, 然后runtimeAPI创建类, 类可以调用协议内的函数和属性.

  • 接口灵活, 可以设计灵活的回调和函数.
  • 没有硬编码
  • 模块间解耦

  • 所有的接口协议文件需要放在一起, 其他模块依赖该模块, 但是不会有实现代码.
  • 使用起来麻烦, 每个调用都需要一个服务和一个协议.

CTMediator

CTMediator target-action的方式

  • 利用NSInvocation类, 使用字符串targetName和字符串actionName转成对应的idSEL类型, 利用NSInvocation类进行方法的调用.(要注意方法的types) 个人认为, CT使用起来还是较为容易出问题, 硬编码太多后期改动会十分麻烦.

  • API简单, 易学.
  • 侵入小
  • 可以解决不同类之间的调用问题

  • 硬编码多,
  • 运行时才可以知道, 编译器无法检 查.

组件化原则

  • 抽象化原则
  • 稳定性原则
  • 从上到下依赖, 组间不依赖.

抽象化原则

  • 最简单的评判标准就是, 上层调用的APi长久不需要改动.
  • 抽象总结的能力
  • 就像苹果官方一样, 每年都要求, 一定要用API, 不要轻易访问内部的数据结构.

稳定性原则

  • 减少依赖, 只要自身稳定, 那么就是稳定
  • 稳定的模块不可以依赖不稳定的模块

从上到下依赖, 组间不依赖, 业务间不依赖.

  • 模块设计上层可以依赖下层, 下层不可以依赖上层.
  • 平级模块间, 不进行依赖.
  • 最好除了最底层的不可缺的依赖, 从上到下的依赖也要尽可能的避免
  • 业务之间不依赖

总结

组件化的方案, 要根据具体的公司规模, 人数可能是发展去制定. 比如你公司只有两个人, 开发很忙, 加入分业务组件, 每一个都做注册, 绑定, 其实是忙不过来的.

  • 人数较多维护的项目, 拆分的粒度一定要细, 可能阿里的这种方案更为合适, 解耦性好, 使用稍微麻烦.
  • 人数较少维护的项目, 可以拆分的粒度很大, 甚至只是分文件夹.
  • 比如一个Model, 在多个业务使用, 3个人的时候可以将其下沉到下部, 上部调用即可. 但是300个人的时候, 其实只能每次接收json从新进行处理更为合适.

没有最好的方案, 只有根据当前的人手, 业务, 项目综合考虑进行方案的选型.

多看一些方案, 其实可以从众取出一些自己觉得好的设计进行融合也是不错.

个人比较建议, 路由的模式以BeeHive为核心, 融合MGJRouter, 然后用懒加载的方式进行模块的初始化. 并且提供非懒加载调用的模式. 系统内存泄漏时候, 可以使用weak链表进行内存的清理等等.多看看总会有很多新奇的想法.