背景
我们有这样一个场景,假如你出差需要报销。你的报销单审批人依次是:项目经理、科室主任、部门负责人、财务负责人。当然你不需要知道每个审批人的姓名、电话号码、办公地址等信息。你不需要自己一个一个的去找这些审批人审批。
常用的解决方式是你发起一个审批需求,你的项目经理审批后提交给科室主任,科室主任审批后提交给部门负责人,部门负责人审批后提交给财务负责人审批。这样你只需要发起一个请求,后面的审批就不需要你操心了。
什么是责任链模式
“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终极版)
另:点击【我的福利】有更多惊喜哦。