发现问题
改造公司一个工程
表面看着是不是还算清爽?我以为她的结构是这样子的:
仔细研究,发现她的结构竟然是这样子的:
除了基本的依赖关系,还有密密麻麻红色部分的依赖关系,模块之间的调用十分严重,这让后期维护的人很头疼,在修改某一模块功能时,可能会影响多个模块。简单说就是耦合性太高。
选择解决方案
既然发现,目前问题是工程耦合性太高,那下一步就是工程解耦。所以就选择用路由器这种方式去解耦:
路由器的作用是:一个消息中转站。
之前模块之间直接相互调用,现在模块之间通过路由器达到通信作用,我们只需要将所有模块依赖于路由器,就解除了模块之间的依赖关系。
目前业内有很多优秀的路由框架,例如阿里的ARouter等等,确实很好用,但这些路由框架有些庞大,很多功能我们可能使用不到,为了减少工程不必要的代码,同时基于路由框架原理也不是很复杂的情况下,还是让我们自己实现一个超轻量级的路由框架,玩耍一下。
超轻量级路由框架SRouter的实现
路由器的核心是一个消息中转站,所以先实现一个消息中转处理类,这里起名SRouter.java。既然是处理转发消息的,那就需要建立相应的消息通道,这里应该支持多通道,可以让不同种类的消息通过不同种类的消息通道来达到传递作用,我们需要一个队列来存储这些不同种类的消息通道,第一步实现如下:
这里首先是一个单例模式,使路由器支持多线程,然后使用HashMap初始化一个队列mActions,用来存储不同种类的消息通道,如上。
消息通道队列初始化之后,就需要实现往队列插入不同消息通道的方法,这里参数包括通道名称action和通道本身SAction.java,如上。
然后就是实现往指定通道发送消息的方法,如上。
实现了SRouter.java,框架就有了基本的路由逻辑控制部分,其中包括了消息通道的建立和发送消息到指定消息通道。在SRouter.java中,看到通道SAction.java的使用,这里说一下这个通道的定义:
通道使用抽象方式的方式实现,参数context是上下文,这个参数意义很重要,用Context就可以跟系统的消息系统对接起来,支持不同场景的消息通信,比如说多进程等等,参数requestData为HashMap类型,支持多种消息类型。
接下来,就要具体定义消息发送的载体类,这里起名SRouterRequest.java。
可以看到,消息发送载体类包含两个部分,action和data,其中action就是通道名称,通过action识别使用哪个消息通道,data就是通道所要传递的消息体,这里重点说一下data,目前定义为HashMap<String,Object>,尽量支持多种消息类型。
到此,基本功能已经有了,但为了让系统成为一个闭环,我们要在消息发送之后,给发送者一个反馈,所以这里就需要实现消息反馈的载体类SRouterResponse.java。
消息反馈的载体类中,包含了statusCode(反馈状态码),statusDesc(反馈状态提示语),body(反馈携带的内容)。
好了,到此,超轻量路由框架已经实现,下来就是赶紧使用一下,体验一把~
使用
我写了一个demo工程(https://github.com/sarlmoclen/SRouterDemo),用这个讲解下如何使用。
第一步:就是初始化通道,通道的建立由自己实际情况决定,本工程中,AppMain,AppChildOneSameProcess,AppChildTwoSameProcess,AppChildThreeDifferentProcess有四个测试module,前三个是在同一进程,最后一个在另外一个进程(测试多进程下路由框架的使用)。所以这里需要四个通道,每个module对应一个通道,用来传递信息。
确认了通道数量,那我们就可以初始化通道了:
通道的建立要尽早,所以放在Application中,我简单封装了一个SApplication.java。这里有个小的重点需要讲一下,在多进程情况下,Application会在每个进程下执行一遍,这样的话,在本demo中有两个进程,所以我们的通道队列就会在每个进程有一个复制(进程有自己的存储空间),我们就利用这一点,让跨进程的情况下,也可以使通道被找到。
第二步:实现通道,在上一步初始化中,可以看到OneAction,TwoAction,ThreeAction,MainAction,这些都是每个module通道的实现,这里以AppMain的通道实现为例子简单说明一下:
可以看到requestData是通道收到的消息,然后我们利用context去传递信息,上面讲过这个context很重要,这里说明一下,在我们开发app时候,使用的就是常说的四大组件(Activity,Service,ContentProvider,BroadcastReceiver),context完美支持了四大组件的通信,当然也支持跨进程。
第三步:发送消息
使用SRouter.java提供的发送消息的方法,给指定通道,发送需要的消息。
方便使用
好了!到此我们就可以随便愉快的玩耍了。
只需给工程根部依赖路由框架,把之前模块间的链接关系切换到路由器上,工程就会恢复清晰的结构。这个小路由已经测试使用了近一年时间,运行良好,SRouter已经被我上传到了maven仓库,方面使用:
compile 'com.sarlmoclen.router:SRouter:0.0.1'
github项目地址:https://github.com/sarlmoclen/SRouterDemo