责任链模式
Chain of Responsibility Pattern:责任链模式,是GoF23种设计模式中属于行为型模式的一种。
责任链模式的主要就是结构是一个链式的结构,一环扣着一环形成一个处理请求的处理链,处理链又不同的对象构成,每个对象可以选择处理或者不处理这个请求,如果处理则这个链就断了,如果不处理就一直延续到下一个对象直到有一个对象处理这个请求为止。
简单的说,责任链模式构造了这样一个情况:使多个不同的对象都有机会处理同一个请求,对请求的发起和接收两个方面形成了解耦合。同时呢,这些对象连接成了一条链,请求沿着这条链进行传递,直到有一个对象处理了这个请求为止。
结构
责任链模式的结构简单,但是使用起来会有一定的复杂度。形成责任链所需要的就是处理者角色,通过类图简单分析一下:
- 处理者角色:定义一个用于处理请求的接口,也是定义统一处理方法的位置。
- 具体处理角色:处理所负责的请求,同时提供可以访问下一层(也就是责任链中的下一个对象)的方法,如果本身就可以处理请求,那就直接处理,否则就需要传递给下一个具体处理对象进行处理。
举例
-
责任链的模式更多的体现在生活之中,比如苦逼的笔者现在在实习,因为大四学校有时候会有必须要回去的活动,像是大学生图像采集啊,体测啊,毕业答辩啊什么什么的,于是这个时候就需要请假了,但是请假申请是需要一步步的往上面传递的。
首先自己提交请假,组长同意之后给总监,总监同意之后给人事,人事同意之后才能告诉我请假成功,可以回校了。
-
代码中的责任链模式例如像是Javascript中的事件冒泡就是这个模式的体现。JS中的事件冒泡,嗯,换个角度说,在DOM中,树状结构觉得是就是子元素被包含在父元素里面,如果一个子元素触发了点击事件,那么父元素也被点击了,父元素的父元素也被点击了,一直到最后的根节点也就是document(或者window)被点击了,这里的事件就会层层冒泡,从事件触发的节点开始,逐层向上级元素传递这个被触发的事件。
注意
- 责任链的优点,笔者自己觉得就是灵活性,不单单的扩展方便,组成责任链的行为结构也是可以任意替换的,这样可以在具体的情况下具体处理,它没有规定必要的次序或者需要遵守什么指定的规范,而是依据实际的要求进行具体的实现,这着实的很灵活的。
- 成也灵活,败也灵活。灵活会导致如果控制不好就会产生奇奇怪怪的问题,比如可能会犯的循环调用的问题,或者是排除BUG的时候,如果责任链一长,那就是一个灾难,一个排BUG的灾难,即使再小的问题,你也得好好的找找。
一个小DEMO
-
场景
嗯,前段时间收获了大学最后一次的奖学金,就以这个为例子吧。
首先呢是自己提交申请
然后呢是辅导员的审批
接着呢是院系的审批
最后呢是学校的审批和发放
林林总总差不多弄了快一个月的时间,啧啧啧,也是恐怖。
-
定义抽象处理类
/** * 责任链模式——抽象处理者 * @author wq */ public abstract class Handler { // 处理者对象 protected Handler handler; // 用于设置责任链中的下一个处理者对象 public void setHandler(Handler handler) { this.handler = handler; } // 处理请求的抽象方法 场景中就是处理奖学金啦 public abstract void handleRequest(int scholarship); }
-
具体的处理类对象
/** * 责任链模式——具体处理者 * 辅导员 * @author wq */ public class Instructor extends Handler{ @Override public void handleRequest(int scholarship) { if (scholarship < 10) { System.out.println("辅导员审核----> 10元以下直接发放"); } else { // 超过了就需要下一层处理了 handler.handleRequest(scholarship); } } } //-------------------------------------------------------------------- /** * 责任链模式——具体处理者 * 院系 * @author wq */ public class Department extends Handler{ @Override public void handleRequest(int scholarship) { if (scholarship < 2000) { System.out.println("院系审核----> 2000元以下直接发放"); } else { // 超过了就需要下一层处理了 handler.handleRequest(scholarship); } } } //---------------------------------------------------------------------- /** * 责任链模式——具体处理者 * 学校 * @author wq */ public class School extends Handler{ @Override public void handleRequest(int scholarship) { // 都到这里了 那就直接发了 这是最高层次了 System.out.println("学校审核----> 2000元以上直接发放"); } }
-
来个测试类
/** * 责任链模式——测试类 * @author wq */ public class Main { public static void main(String[] args) { // 首先构建这条责任链 Handler instructor = new Instructor(); Handler department = new Department(); Handler school = new School(); // 辅导员的后继是院系 instructor.setHandler(department); // 院系的后继是学校 department.setHandler(school); // 首先由自己发出请求,第一道关卡是辅导员 int[] scholarship = {1,1000,4000}; for (int i = 0; i < scholarship.length; i++) { instructor.handleRequest(scholarship[i]); System.out.println("----------万恶的分割线------------"); } } }
-
测试走一波
辅导员审核----> 10元以下直接发放 ----------万恶的分割线------------ 院系审核----> 2000元以下直接发放 ----------万恶的分割线------------ 学校审核----> 2000元以上直接发放 ----------万恶的分割线------------
完成!!!