定义:将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求,如果能则处理,如果不能则传递给链上的下一个对象。
场景:打牌时,轮流出牌;接力赛跑;大学中,奖学金审批;公司中,公文审批
——公司里,报销单据需要经过流程:
申请人填单申请,申请给经理
小于1000,经理审查
超过1000,交给总经理审批
总经理审批通过
——公司里面,请假条审批过程:
如果请假天数小于3天,主任审批
如果请假天数大于等于3天,小于10天,经理审批
如果大于等于10天,小于30天,总经理审批
如果大于等于30天,提示拒绝
以上面请假条审批过程为例:
1. 创建一个LeaveRequst类:
1 package com.ztq.chainOfResp; 2 3 /*** 4 * 封装请假的基本信息 5 * @author ZTQ 6 * 7 */ 8 public class LeaveRequest { 9 private String empName; 10 private int leaveDays; 11 private String reason; 12 13 public LeaveRequest(String empName, int leaveDays, String reason) { 14 super(); 15 this.empName = empName; 16 this.leaveDays = leaveDays; 17 this.reason = reason; 18 } 19 public String getEmpName() { 20 return empName; 21 } 22 public void setEmpName(String empName) { 23 this.empName = empName; 24 } 25 public int getLeaveDays() { 26 return leaveDays; 27 } 28 public void setLeaveDays(int leaveDays) { 29 this.leaveDays = leaveDays; 30 } 31 public String getReason() { 32 return reason; 33 } 34 public void setReason(String reason) { 35 this.reason = reason; 36 } 37 38 }
2.创建Leader抽象类:
1 package com.ztq.chainOfResp; 2 3 /*** 4 * 抽象类 5 * @author ZTQ 6 * 7 */ 8 public abstract class Leader { 9 protected String name; 10 protected Leader nextLeader; //责任链上的后继对象 11 public Leader(String name) { 12 super(); 13 this.name = name; 14 } 15 16 //设定责任链的后继对象 17 public void setNextLeader(Leader nextLeader) { 18 this.nextLeader = nextLeader; 19 } 20 21 //处理请求的核心的业务方法 22 public abstract void handleRequest(LeaveRequest request); 23 }
3. 创建Director类:
1 package com.ztq.chainOfResp; 2 3 /*** 4 * 主任 5 * @author ZTQ 6 * 7 */ 8 public class Director extends Leader{ 9 10 public Director(String name) { 11 super(name); 12 13 } 14 15 @Override 16 public void handleRequest(LeaveRequest request) { 17 if(request.getLeaveDays() < 3){ 18 System.out.println("员工:" + request.getEmpName() + "请假,天数:" + request.getLeaveDays() + ", 理由:" + request.getReason()); 19 System.out.println("主任:" + this.name + "审批通过!"); 20 }else{ 21 if(this.nextLeader != null){ 22 this.nextLeader.handleRequest(request); 23 } 24 } 25 } 26 27 }
4. 创建Manager类:
1 package com.ztq.chainOfResp; 2 3 /*** 4 * 经理 5 * @author ZTQ 6 * 7 */ 8 public class Manager extends Leader{ 9 10 public Manager(String name) { 11 super(name); 12 13 } 14 15 @Override 16 public void handleRequest(LeaveRequest request) { 17 if(request.getLeaveDays() < 10){ 18 System.out.println("员工:" + request.getEmpName() + "请假,天数:" + request.getLeaveDays() + ", 理由:" + request.getReason()); 19 System.out.println("经理:" + this.name + "审批通过!"); 20 }else{ 21 if(this.nextLeader != null){ 22 this.nextLeader.handleRequest(request); 23 } 24 } 25 } 26 27 }
5.创建GeneralManager类:
1 package com.ztq.chainOfResp; 2 3 /*** 4 * 总经理 5 * @author ZTQ 6 * 7 */ 8 public class GeneralManager extends Leader{ 9 10 public GeneralManager(String name) { 11 super(name); 12 13 } 14 15 @Override 16 public void handleRequest(LeaveRequest request) { 17 if(request.getLeaveDays() < 30){ 18 System.out.println("员工:" + request.getEmpName() + "请假,天数:" + request.getLeaveDays() + ", 理由:" + request.getReason()); 19 System.out.println("总经理:" + this.name + "审批通过!"); 20 }else{ 21 System.out.println("莫非" + request.getEmpName() + "想辞职,居然请假" + request.getLeaveDays() + "天!"); 22 } 23 } 24 25 }
6.创建测试类Client:
1 package com.ztq.chainOfResp; 2 3 public class Client { 4 public static void main(String[] args) { 5 Leader a = new Director("张三"); 6 Leader b = new Manager("李四"); 7 Leader c = new GeneralManager("王五"); 8 9 //组织责任链对象的关系 10 a.setNextLeader(b); 11 a.setNextLeader(c); 12 13 //开始请假操作 14 LeaveRequest req1 = new LeaveRequest("Tom", 10, "回英国老家探亲!"); 15 a.handleRequest(req1); 16 } 17 }
7.运行结果:
员工:Tom请假,天数:10, 理由:回英国老家探亲!
总经理:王五审批通过!
8.UML图:
开发中常见的场景:
——Java中,异常机制就是一种责任链模式。一个try可以对应多个catch,当第一个catch不匹配类型,则自动跳到第二个catch。
——JavaScript语言中,事件的冒泡和捕获机制。Java语言中,事件的处理采用观察者模式。
——Servlet开发中,过滤器的链式处理
——Struts2中,拦截器的调用也是典型的责任链模式