简介:
今天介绍两种设计模式给大家
第一个是在工作中笔者利用Spring容器提供的通过beanName获取bean的功能,想到了一种设计,称之为Spring工厂模式。
第二个是责任链模式。
应用场景:
横向拓展的场景,当程序中实现方案依赖于请求条件的不同而不同时(只会有唯一的一个实现类去处理),即可使用此设计模式
举个栗子:
现在有个场景,当我rpc请求中orderSource字段的值为ctrip的时候,我就要去调携程的订单接口查询订单并有携程专属逻辑,当我orderSource字段为qunar的时候,我就要去调去哪儿的订单接口查询订单并有去哪儿专属逻辑。也就是application层入参不用时,就会走完全不同的处理逻辑,可能有公共的逻辑,也有可能完全独立,一般最初的实现可能会是这么写:
当然省略了很多细节,比如查询条件,service内部处理,并且用controller表示rpc请求,这些具体的细节不影响结构。
![](https://img.haomeiwen.com/i11772383/707fe1b89faf03e3.png)
如果说这两个service实现类有公共的逻辑,可能会组合或者继承的方式去复用一些代码,但是总体拓展下去,新增一个来源的话,就需要新增一个service实现类,并且在application这一层新增service注入,以及条件分支,这样application层和service耦合严重,依赖具体实现,并且条件分支写多了可读性差。
下面针对以上代码,换成Spring工厂的实现来看看
![](https://img.haomeiwen.com/i11772383/e679d083f7139901.png)
![](https://img.haomeiwen.com/i11772383/f930a5f204f75958.png)
![](https://img.haomeiwen.com/i11772383/074a313e250f1850.png)
![](https://img.haomeiwen.com/i11772383/ab3b60cf0b70268a.png)
没错,正是利用Spring可以通过beanName获取bean实例的特性,将横向拓展的service放到工厂中,利用一个Map维护service的映射规则,找到专属的service去实现,如果请求参数是两个纬度,可以使用guava的Table这种嵌套map性质的集合保存mapping关系,原理一样,也可以把多个字段组装一个复杂的key,反正value都是bean的name,key这边自由发挥。application层依赖抽象,不依赖具体实现,拓展的话,只需要新增service,并且在工厂map中注册即可,application层完全不需要改动。当然,这个map如果采用分布式配置中心的话,连map都不需要改动,只需要在配置中心修改新增key值即可,类似apollo或者qconfig。
有读者可能会说,可以写一个service实现类,在内部去走条件分支,这样application层就依赖抽象不耦合。
当然,一般项目模块划分,application层确实都是只依赖domain抽象,具体实现都在port层,我举的例子是描述一种场景,不纠结规范的问题。
如果只用一个service实现类去做这件事,实现类里还是需要去重现上述逻辑,为了功能单一化,可能会抽离一些不同manager去做横向拓展,那道理其实一样,只不过这个例子是在application层做的工厂,重要的是表达一种设计想法。
如果换成责任链模式呢?
![](https://img.haomeiwen.com/i11772383/f55ad879b53129c2.png)
![](https://img.haomeiwen.com/i11772383/0708bf925c4c314e.png)
![](https://img.haomeiwen.com/i11772383/222614465d46f7c5.png)
![](https://img.haomeiwen.com/i11772383/76df32719b676a25.png)
![](https://img.haomeiwen.com/i11772383/f388c819c38c1336.png)
个人想法:
上述两种设计模式思想都是根据条件寻找唯一的一种实现。
区别在于查找实现的方式不同,Spring工厂是通过mapping注册维护参数与beanName的关系,然后从Spring中获取唯一的bean去实现。而责任链模式是通过把实现挂链表,然后递归循环查找,直到有人处理。就思想、拓展复杂度和性能而言,笔者认为这两种方式都很接近,可能查找实现上性能看起来一个是O(1)一个是O(n),但是一般实现类数量有限。
你们怎么看这两种模式的优劣呢?
网友评论