设计模式10之责任链模式

背景

我们有这样一个场景,假如你出差需要报销。你的报销单审批人依次是:项目经理、科室主任、部门负责人、财务负责人。当然你不需要知道每个审批人的姓名、电话号码、办公地址等信息。你不需要自己一个一个的去找这些审批人审批。

常用的解决方式是你发起一个审批需求,你的项目经理审批后提交给科室主任,科室主任审批后提交给部门负责人,部门负责人审批后提交给财务负责人审批。这样你只需要发起一个请求,后面的审批就不需要你操心了。

什么是责任链模式

Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object handles it.(使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。)

责任链模式优点显而易见,降低了请求对象与处理对像之间的耦合度,处理对象易于扩展,增强了指派处理对象的灵活性。

责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。

链式结构

责任链模式主要由3个要素组成:

  • 抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。

  • 具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。

  • 客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

结构图如下:

责任链结构图

代码实现

Handler

定义抽象执行类,里面有一个抽象处理请求的方法。

ConcreteHandler1

Handler的实现类,同样的我们可以扩展这个实现类ConcreteHandler2

测试代码如下:

测试结果:

具体处理者2负责处理该请求!

关于对责任链模式的看法

那么我们什么时候合适使用责任链模式呢?

一般如果由多个对象处理一个请求,需要使用哪对象由实际调用的时候确定。这种场景我们就可以使用调用者模式。

如果你开发过管理系统,是否有过流程审批功能的开发。大家可以思考下这方面能不能使用责任链模式呢。

还有在订单系统中,订单状态的处理是否可以使用此种设计模式更为优秀呢。

但是,要注意的是,对象里面采用了递归的方式,如果链路较长,对系统的性能也会有一定的影响。所以使用责任链模式需要控制链路长度。比如在Handler中设置最大节点数量。如果节点数量超出这个最大数量,就不允许该链路的创立。

在责任链模式中,各个实现类只要关注的自己业务逻辑就成了,至于说什么事要自己处理,那就让父类去决定好了,也就是说父类实现了请求传递的功能,子类实现请求的处理,符合单一职责原则,各个实现类只完成一个动作或逻辑。

责任链模式可以很好的扩展节点。这里有一个场景,比如开发一个报销审批系统,最开始你只是开发了只要项目经理报销就可以了。但是实际情况是报销金额太大,项目经理做不了主了,需要部门经理来报销了。如果使用责任链模式,我们就可以在第一个处理者后面建立一个部门经理的新节点。实际调用的时候只要选取这个部门经理的节点。

你看,这种扩展方式很好的解决了需求变更问题。

往期推荐

扫码二维码,获取更多精彩。或微信搜Lvshen_9,可后台回复获取资料

1.回复"java" 获取java电子书;

2.回复"python"获取python电子书;

3.回复"算法"获取算法电子书;

4.回复"大数据"获取大数据电子书;

5.回复"spring"获取SpringBoot的学习视频。

6.回复"面试"获取一线大厂面试资料

7.回复"进阶之路"获取Java进阶之路的思维导图

8.回复"手册"获取阿里巴巴Java开发手册(嵩山终极版)

9.回复"总结"获取Java后端面试经验总结PDF版

10.回复"Redis"获取Redis命令手册,和Redis专项面试习题(PDF)

11.回复"并发导图"获取Java并发编程思维导图(xmind终极版)

另:点击【我的福利】有更多惊喜哦。

猜你喜欢

转载自blog.csdn.net/wujialv/article/details/109193591