设计模式(十二)责任链模式

定义:将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求,如果能则处理,如果不能则传递给链上的下一个对象。

场景:打牌时,轮流出牌;接力赛跑;大学中,奖学金审批;公司中,公文审批

——公司里,报销单据需要经过流程:

  申请人填单申请,申请给经理

  小于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中,拦截器的调用也是典型的责任链模式

原文地址:https://www.cnblogs.com/zhangtianq/p/6119938.html