今天,我们来分享行为型模式的另外一个成员:责任链模式。
责任链模式是一种行为型模式,它允许多个对象来处理请求,从而避免了请求的发送者和接收者之间的直接耦合。
其实,在平时生活或者工作中,我们经常能看到责任链的影子,比如请假和打折的场景。
场景1:请假
某天你想请个假,比如1到3天,直接主管可以审批;3天以上需要部门主管审批;15天以上需要副总裁审批 ... ...
场景2:打折
某天你去买个车,和销售人员讨论折扣的问题。这个时候,可能95折以上销售能拍板;85折需要销售经理拍板;75折需要区域经理拍板 ... ...
这些场景,当某一个人或者节点不能处理的时候,需要抛给下一个节点处理。也就是,每个对象都可以决定是否处理请求或将其传递给下一个对象来处理。这就是我们今天要聊的责任链模式可以做的事情。
意图
责任链的意图是使多个对象都有机会处理请求,从而避免请求的发送者和接收者之前的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
结构
责任链模式的基本结构如下:
Handler
定义一个处理请求的接口。
ConcreteHandler
接下来,我们给一个责任链模式示例模拟买东西打折扣,规则如下:
销售人员能处理9折以上的折扣;如果折扣低于9折向销售经理请示;同理,销售经理能处理8折以上的折扣,如果折扣低于8折,其需要向区域经理请示;区域经理能处理7折以上的折扣。
DiscountHandler (Handler)
折扣处理类,其包含一个折扣处理方法handle, 还有一个后继处理者 successor。
3个ConcreteHandler
定义三个具体的处理者类,分别对应销售人员、销售经理以及区域经理的处理,代码如下:
客户端
模拟不同折扣,测试一下;
输出:
这样,一个获取折扣的责任链模式示例就完成了。
问题来了?
上面的例子很简单,但是责任链的构建不灵活,比如:
需要每个具体处理器去指定后继者(next),如果中间几某一个节点需要增加一个新的,需要手动调整下后继next。有没有一种方式,相对可以灵活一点呢?
接下来,我们写一个Builder工具来完成。
责任链Builder构建工具
在Client端使用如下代码来进行构建。
完整Client端代码如下:
同样运行一下,我们依然可以获取同样的效果。
责任链的多种实现方式
责任链的每一个处理节点其实就是2点。
如果将多个处理节点串联起来,一般有如下几种方式:
手动置顶
基于配置文件
比如javax.servlet.Filter,我们可以配置xml来将其串联起来。
基于链表的方式
上述,我们给出了一个结合Builder模式,使用头尾2个节点,把处理器串联起来。
其实,比如处理器返回一个true or false,或者有一个方法展示该节点是否能处理。我们也可以使用基于List或者数组的Chain来完成。接下来,稍微做点调整,为了简单模式,处理器的handle方法返回一个boolean类型。
使用一个List来将各个处理器关联起来。然后,处理器按一个for循环进行处理,只要有一个返回true,就表示已处理,退出循环。如:
客户端Client修改测试一下,同样能拿到结果。
基于注解
也可以写一个注解比如@Chain,比如一个group、name和next属性。含义如下:
然后在相关处理器类中标注该注解,可以通过反射对处理器所在package进行扫描,然后将标注@Chain注解的处理器按Group进行分组,并根据name和next串联起来。有兴趣的读者可以自己实现一把。
当然,如果不想使用name或者next,也可以使用一个order属性,指定1,2,3 .... .... 同样也可以按照从小到大完成顺序的串联。
优缺点
优点:
缺点:
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。