经过上面的分析,可以发现,路由的设计思路是从URLRoute ->Protocol-class ->Target-Action一步步的深入的过程。这也是逐渐深入本质的过程。
[
](https://github.com/halfrost/Halfrost-Field/blob/master/contents/iOSRouter/iOS%20%E7%BB%84%E4%BB%B6%E5%8C%96%20%E2%80%94%E2%80%94%20%E8%B7%AF%E7%94%B1%E8%AE%BE%E8%AE%A1%E6%80%9D%E8%B7%AF%E5%88%86%E6%9E%90.md#1-urlroute注册方案的优缺点)1. URLRoute注册方案的优缺点
首先URLRoute也许是借鉴前端Router和系统App内跳转的方式想出来的方法。它通过URL来请求资源。不管是H5,RN,Weex,iOS界面或者组件请求资源的方式就都统一了。URL里面也会带上参数,这样调用什么界面或者组件都可以。所以这种方式是最容易,也是最先可以想到的。
URLRoute的优点很多,最大的优点就是服务器可以动态的控制页面跳转,可以统一处理页面出问题之后的错误处理,可以统一三端,iOS,Android,H5 / RN / Weex 的请求方式。
但是这种方式也需要看不同公司的需求。如果公司里面已经完成了服务器端动态下发的脚手架工具,前端也完成了Native端如果出现错误了,可以随时替换相同业务界面的需求,那么这个时候可能选择URLRoute的几率会更大。
但是如果公司里面H5没有做相关出现问题后能替换的界面,H5开发人员觉得这是给他们增添负担。如果公司也没有完成服务器动态下发路由规则的那套系统,那么公司可能就不会采用URLRoute的方式。因为URLRoute带来的少量动态性,公司是可以用JSPatch来做到。线上出现bug了,可以立即用JSPatch修掉,而不采用URLRoute去做。
所以选择URLRoute这种方案,也要看公司的发展情况和人员分配,技术选型方面。
URLRoute方案也是存在一些缺点的,首先URL的map规则是需要注册的,它们会在load方法里面写。写在load方法里面是会影响App启动速度的。
其次是大量的硬编码。URL链接里面关于组件和页面的名字都是硬编码,参数也都是硬编码。而且每个URL参数字段都必须要一个文档进行维护,这个对于业务开发人员也是一个负担。而且URL短连接散落在整个App四处,维护起来实在有点麻烦,虽然蘑菇街想到了用宏统一管理这些链接,但是还是解决不了硬编码的问题。
真正一个好的路由是在无形当中服务整个App的,是一个无感知的过程,从这一点来说,略有点缺失。
最后一个缺点是,对于传递NSObject的参数,URL是不够友好的,它最多是传递一个字典。
[
](https://github.com/halfrost/Halfrost-Field/blob/master/contents/iOSRouter/iOS%20%E7%BB%84%E4%BB%B6%E5%8C%96%20%E2%80%94%E2%80%94%20%E8%B7%AF%E7%94%B1%E8%AE%BE%E8%AE%A1%E6%80%9D%E8%B7%AF%E5%88%86%E6%9E%90.md#2-protocol-class注册方案的优缺点)2. Protocol-Class注册方案的优缺点
Protocol-Class方案的优点,这个方案没有硬编码。
Protocol-Class方案也是存在一些缺点的,每个Protocol都要向ModuleManager进行注册。
这种方案ModuleEntry是同时需要依赖ModuleManager和组件里面的页面或者组件两者的。当然ModuleEntry也是会依赖ModuleEntryProtocol的,但是这个依赖是可以去掉的,比如用Runtime的方法NSProtocolFromString,加上硬编码是可以去掉对Protocol的依赖的。但是考虑到硬编码的方式对出现bug,后期维护都是不友好的,所以对Protocol的依赖还是不要去除。
最后一个缺点是组件方法的调用是分散在各处的,没有统一的入口,也就没法做组件不存在时或者出现错误时的统一处理。
[
](https://github.com/halfrost/Halfrost-Field/blob/master/contents/iOSRouter/iOS%20%E7%BB%84%E4%BB%B6%E5%8C%96%20%E2%80%94%E2%80%94%20%E8%B7%AF%E7%94%B1%E8%AE%BE%E8%AE%A1%E6%80%9D%E8%B7%AF%E5%88%86%E6%9E%90.md#3-target-action方案的优缺点)3. Target-Action方案的优缺点
Target-Action方案的优点,充分的利用Runtime的特性,无需注册这一步。Target-Action方案只有存在组件依赖Mediator这一层依赖关系。在Mediator中维护针对Mediator的Category,每个category对应一个Target,Categroy中的方法对应Action场景。Target-Action方案也统一了所有组件间调用入口。
Target-Action方案也能有一定的安全保证,它对url中进行Native前缀进行验证。
Target-Action方案的缺点,Target_Action在Category中将常规参数打包成字典,在Target处再把字典拆包成常规参数,这就造成了一部分的硬编码。
[
](https://github.com/halfrost/Halfrost-Field/blob/master/contents/iOSRouter/iOS%20%E7%BB%84%E4%BB%B6%E5%8C%96%20%E2%80%94%E2%80%94%20%E8%B7%AF%E7%94%B1%E8%AE%BE%E8%AE%A1%E6%80%9D%E8%B7%AF%E5%88%86%E6%9E%90.md#4-组件如何拆分)4. 组件如何拆分?
这个问题其实应该是在打算实施组件化之前就应该考虑的问题。为何还要放在这里说呢?因为组件的拆分每个公司都有属于自己的拆分方案,按照业务线拆?按照最细小的业务功能模块拆?还是按照一个完成的功能进行拆分?这个就牵扯到了拆分粗细度的问题了。组件拆分的粗细度就会直接关系到未来路由需要解耦的程度。
假设,把登录的所有流程封装成一个组件,由于登录里面会涉及到多个页面,那么这些页面都会打包在一个组件里面。那么其他模块需要调用登录状态的时候,这时候就需要用到登录组件暴露在外面可以获取登录状态的接口。那么这个时候就可以考虑把这些接口写到Protocol里面,暴露给外面使用。或者用Target-Action的方法。这种把一个功能全部都划分成登录组件的话,划分粒度就稍微粗一点。
如果仅仅把登录状态的细小功能划分成一个元组件,那么外面想获取登录状态就直接调用这个组件就好。这种划分的粒度就非常细了。这样就会导致组件个数巨多。
所以在进行拆分组件的时候,也许当时业务并不复杂的时候,拆分成组件,相互耦合也不大。但是随着业务不管变化,之前划分的组件间耦合性越来越大,于是就会考虑继续把之前的组件再进行拆分。也许有些业务砍掉了,之前一些小的组件也许还会被组合到一起。总之,在业务没有完全固定下来之前,组件的划分可能一直进行时。