一、url-block
启动时注册组件提供的服务,把调用组件所使用的URL 和 组件提供的服务block对应起来,保存在内存中,在使用时候通过url找到对应的block从而获取服务;
[MGJRouter registerURLPattern:@"[mgj://detail?id=:id](mgj://detail?id=:id)" toHandler:^(NSDictionary *routerParameters) {
NSNumber *id = routerParameters[@"id"];
// create view controller with id
// push view controller
}];
[MGJRouter openURL:@"[mgj://detail?id=404](mgj://detail?id=404)"]
优点:
1、h5和app的原生交互,都可以直接使用这些定义好的路由;
2、统一iOS和Android的平台差异性,专门用后台来管理url,然后针对不同的平台,生成不同类型的文件,来方便使用;
缺点:
1、需要在内存中维护url-block的表,组件多了可能会有内存问题;
2、url的参数传递受到限制,只能传递常规的字符串参数,无法传递非常规参数,如UIImage、NSData等类型;
3、没有区分本地调用和远程调用的情况,尤其是远程调用,会因为url参数受限,导致一些功能受限;
4、组件本身依赖了中间件,且分散注册使的耦合较多;
5、url注册对于实施组件化是完全没有必要的,查找 URL 的实现不够高效;
6、路由写错后编译没问题,而实现运行就出问题了,不利于维护;
二、 protocol-class
通过protocol 来定义服务接口,组件通过实现该接口来提供接口定义的服务,具体实现是通过protocol 和 class做一个映射,同时在内存中保存一张映射表,使用的时候通过protocol来找到对应的class获取相应的服务。
[ModuleManager registerClass:ClassA forProtocol:ProtocolA]
[ModuleManager classForProtocol:ProtocolA]
优点:
1、相对url-block方案来讲,解决了不能传递非常规参数的问题;
2、耦合代码量减少了,也利于日后的维护;
3、协议方法未实现的话,编译会报警告;
4、方法查找容易,调用比较高效;
缺点:
1、组件的方法调用比较分散;
2、内存中依然需要维护映射对应关系的表;
3、组件的协议需要注册,不注册就无法使用;
三、target-action
组件通过wrapper封装来给外界提供服务,调用者通过依然中间件来调用服务,而中间件是通过runtime来调用组件服务的,实现真正意义上的解耦,这是该方案最核心的地方,具体实现是给组件封装一个Target对象来对外提供服务,这样不会对原来组件造成入侵,然后调用者通过调用中间件category定义的接口来获取服务,这样调用者只需要依赖中间件而组件不需要依然中间件。
优点:
1、内存中不需要维护映射表;
2、不需要注册;
缺点:
1、中间件实现比较繁琐;
2、中间件方法、参数、返回值不够灵活;
3、中间件内部使用字符串来调用类和方法,如果字符串写错了,在编译期不会报错,但运行后会报错,不利于日后的维护;