meituan / WMRouter

WMRouter是一款Android路由框架,基于组件化的设计思路,有功能灵活、使用简单的特点。
https://tech.meituan.com/meituan_waimai_android_open_source_routing_framework.html
Apache License 2.0
2.31k stars 342 forks source link

整体设计感觉挺好,但有点疑问,为什么要让注解那么分散? #31

Closed tyzero closed 5 years ago

tyzero commented 5 years ago

有时候页面非常多,路由改起来非常不直观。

为什么不把路由统一配置在一个文件里面呢?每个activity都在头部单独注解,没有好处呀。 我觉得前端Vue的route就很不错,一个文件配置 一切路由,查看的时候,也一览无遗。

还有些是有父子关系的,把他们放在一起,肯定会直观很多。

比如 /home/ /home/me/ /home/a/ /home/a/b

/function/xx /function/bb (这里的home和function 都不是host, 语义上是path)

而且有的path是基于父子关系,假如home是登陆用户才能进入的,那么只要在home这个父路径设置权限拦截器就可以了。而a 这个子路径只有管理员权限的用户才能进入,那么只要在a这个子路径设置一个拦截器就可以了。

至于如何把路由配置统一在一个文件,假如还是用注解来实现,我的建议是参考retrofit2那样。

但是我还是不喜欢注解,虽然已经把项目拆成了一个个小项目,编译时注解依旧是编译打包中最耗时的操作。(项目用到了大量编译时注解,还有databinding,现在已经后悔了)

一点小小的愚见,我更倾向于直接用java类来实现路由配置。假如是用kotlin,我觉得可以这样

class Router: WmRouter(){

   build{
     addRoute("/home",HomeActivity:class.java){
          seItnterceptor(LoginInterceptor::class.java)
          addChild{
               addRoute("/me",MeFragment:class.java)
               addRoute("/a",AFragment:class.java)
               addRoute("/b", BFragment:class.java)

         }
     }
  }

} 
zkywalker commented 5 years ago

统一配置会提高耦合度吧

jzj1993 commented 5 years ago

你说的有一定道理,但是这个是看具体情况的。

首先WMRouter是可以像你说的那样用代码集中配置所有Activity的。

其次,集中式配置通常更适合小工程,而大工程有时候还是需要分散配置,WMRouter里的注解就是为了实现分散配置而设计的。

对于一个比较大的工程,可能里面会有几百个Activity,有好几十上百的开发人员,而且可能是有多个业务组一起开发的(可能都不在一个城市办公)。这个时候如果还是集中式处理,每个人都要在同一个地方修改配置,代码冲突问题会很严重,沟通成本是很高的。同时由于主工程依赖所有子工程并进行集中配置,只要任何一个子工程的Activity做了改动,而主工程没有同步更新(也就是要经过代码commit, push, pull request, CI, review, merge, pull这一系列操作),都会导致项目没法编译,严重影响开发。

所以用注解分散式配置就很有必要了,各个业务库之间没有直接关联,主工程也不需要依赖业务库。没有同步更新最多只会导致变动的Activity不能打开,不会编译不过,也不会影响其他业务的Activity。虽然注解确实影响编译速度,但是相比频繁的代码冲突、项目无法编译,还是好多了。

关于注解耗时的问题,WMRouter的插件也是尽量做了优化,耗时最主要是在Transform解压和重新压缩jar包上,而WMRouter是直接生成了一个新的Class,并且用的ASM,也不需要像Javassist一样加载class到ClassPool,已有的jar包直接复制就行了,所以性能还是比较好的(这块个人觉得还是Android Gradle Plugin的问题,对外只提供了一个Transform接口,jar包和class文件即使不需要修改也必须复制一遍,其实是有优化空间的)。

你说的Vue Router,Vue是用来实现单页面应用的,不太适合大型网站,所以集中式管理是合理的。一些Web路由框架是可以实现级联的,比如顶层Router根据不同的前缀再分发给子Router,一层一层的分发,这样设计也是方便实现分散式配置。

xiaojinzi123 commented 5 years ago

其实这个是可以做到的, WMRouter 应该暂时没有这个功能.其实你就讨论跳转的方面,跳转无非就是系统的一个 Intent,而这个 Intent 如果可以提供自定义的操作,其实就可以做到题主说的统一配置在一个文件中.但是也有很多人是喜欢在每一个 Activity 上定义的.我就是其中一个. 关于自定义 Intent 的方式,你可以看下我的Component组件化方案, wiki 中的 RouterAnno 注解 的自定义 Intent 部分可以满足你的需求