从实践中体会dispatcher模式
概念解释
所谓dispatcher模式就是一个集中然后分发的模式,类似邮件的派发。我们将我们发往各地的快递或者是信件投递到邮局,然后邮局负责将各个邮件派发到信封上面的目的地。那么此时,我们就可以看做是一个服务的请求者,我们将我们的不同的需求提交给邮局,而邮局可以看做是一个分发器,我们的服务分发给各个服务的具体提供者。此时,邮局也可以看做一个路由,就是起到了一个分发的作用。这就是Dispatcher模式。
实际问题
前段时间我们做的项目要向外提供开发端口,也就是提供我们内部的服务给第三方接入。为了安全,肯定不能直接把我们内部的接口暴露给外面,所以需要对内部的服务进行一次封装。然后再给第三方调用。组长和我说,不要通过if else来判断具体调用哪个服务,只要通过第三方发送过来的信息就可以判断调用哪个具体的服务。当时我第一个想到的就是dispatcher。于是我就先基于dispatcher搭建起了基本的框架。
实际问题解决
我对对外提供的服务进行了一个抽象,定义了一个接口。这个接口IA里面有一个doService方法,用来执行该服务所处理的实际业务逻辑,还有一个就是getName方法,用来获取当前服务名,最后一个是isEnable用来判断当前服务是否有效,进行一个状态的判断。这是服务的基本定义。同时我对这个接口进行了一个抽象的实现AbA,只是先了一个getName方法,因为这个方法只是生成一个服务名,可以用统一的规则生成。所以以后每个服务只需要继承AbA这个抽象就可以了,同时实现里面另外两个方法。并且将这个实现服务注册到spring中,通过Spring来管理(也可以不通过Spring,通过反射也可以)。
这些服务就是对于不同业务和不同请求的实际处理者。对应了开始距离中的各个目的地。在此之上,我还定义了一个Dispathcer类,这个类主要的功能就是分发各个请求,将请求分发到对应的处理实例中去。在这个类中,我们通过一个Map对象来缓存所有的服务,key为服务名,value为服务实例。通过Spring的Application中的一个接口可以得到所有实现了IA接口的Bean。我们将这个集合遍历,调用每个bean的getName方法作为Map的key,将bean实例作为Map的value。这样就初始化了这个Map。在Dispatcher类获得请求需要请求的服务名,然后再Map里面获取,得到value,然后执行相应的业务。这就完成了分发的操作。
该设计模式的优点
这种设计模式对于以后添加新的服务可以不要修改任何代码,只需要集成AbA这个抽象类,然后注册到Spring中。至于请求怎么到你这的,你可以不需要考虑,这可以说是透明的。所以,这种模式,当新的业务添加的时候,可以对代码的框架进行很小的修改几乎不改,不需要将注意力放到整个处理流程上,而只需放到具体的业务上。简化了开发的过程,同时也使得代码简洁。
其他方法的配合
该问题,由于业务处理完毕时候,返回给第三方的是一个XML字符串,所以服务返回的数据很可能是XML字符串,那么要在每个服务里面拼装XML字符串,这感觉是一件很没有意义的事情,将POJO转换成XML可以通过反射来拼装XML,这可以写一个通用的工具方法。那么这样还是会使得在服务里面拼装XML,那么如何避免呢?那么就需要设计好返回数据的VO了,并且每个VO里面自动去生成对应该VO的xml字符串。那么在处理具体业务的时候,我们就没必要去做一些没有意义的拼装XML了,只需要将要返回的数据封装到返回的VO中,由这个VO去为我们生成XML。这样就可以使得编写代码又清晰了很多,而且简单。这种方法,我也不知道是哪种设计模式,可能还没有接触到的名词吧,我这里就称它为分工明确模式。就是,自己只处理属于自己范围内的事情,而不处理超出自己范围的事情,对于超出的事情,就交给其他类去做吧,要不设计新的类来处理。