专业编程基础技术教程

网站首页 > 基础教程 正文

设计模式之责任链模式,这样学So Easy

ccvgpt 2024-08-20 12:56:14 基础教程 9 ℃

什么是责任链模式

为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一个对象记住下一个对象的引用 而成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。

责任链模式,也叫职责链模式,属于行为型设计模式。

设计模式之责任链模式,这样学So Easy


责任链模式类图

责任链模式角色

  • 抽象处理者角色(Handler): 定义一个处理请求的接口,包含抽象处理方法和一个后续连接。
  • 具体处理者角色(ConcreteHandler): 实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理则处理,否则该请求转给它的后继者。

责任链模式优缺点

  • 优点

降低了请求者和接受者对象之间的耦合度。


增强了系统的可扩展性,新增处理类时,满足开闭原则。


增强了给对象指派职责的灵活性:当流程工作发生变化时,可以根据需要动态调整责任链的顺序,也可新增或删除责任链。


责任链简化了对象之间的连接:一个责任链只需保持一个其后继者的引用,无需保持其它处理者的引用。


责任链分工明确:每个责任链只需要处理自己该处理的工作,不能处理的传递给下一个对象完成,满足单一职责原则

  • 缺点

不能保证每个请求都能被处理。


对比较长的责任链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。


责任链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能由于责任链的错误设置而导致系统出错。


责任链模式Demo需求

以请假审批流程为例,公司员工请假审批流程是:员工请假天数小于3天,小组长审批;请假天数小于10天,部门经理审批;请假天数小于20天,副总经理审批;请假天数小于30天,总经理审批;请假天数超过30天,不予审批。


责任链模式源代码示例

 /**
  * 请假类
  */
 public class LeaveRequest {
     //请假人
     private String name;
     //请假理由
     private String reason;
     //请假天数
     private int day;
 
     public LeaveRequest(String name, String reason, int day) {
         this.name = name;
         this.reason = reason;
         this.day = day;
     }
 
     public String getName() {
         return name;
     }
 
     public void setName(String name) {
         this.name = name;
     }
 
     public String getReason() {
         return reason;
     }
 
     public void setReason(String reason) {
         this.reason = reason;
     }
 
     public int getDay() {
         return day;
     }
 
     public void setDay(int day) {
         this.day = day;
     }
 }
 
 
 /**
  * 抽象处理者角色:请假流程抽象类
  */
 public  abstract class Leader {
     //审批人
     protected String name;
     //下一个审批者
     protected Leader nextLeader;
 
     public Leader(String name) {
         this.name = name;
     }
 
     public void setNextLeader(Leader nextLeader) {
         this.nextLeader = nextLeader;
     }
 
     /**
      * 请假审批
      * @param request
      */
     public abstract void approve(LeaveRequest request);
 }
 
 /**
  * 具体处理者角色:小组长审批
  */
 public class Headman extends Leader {
 
     public Headman(String name) {
         super(name);
     }
 
     public void approve(LeaveRequest request) {
         //审批请假天数小于3天
         if(request.getDay()<=3){
             System.out.println("请假人:"+request.getName()+", 请假天数:"+request.getDay()+", 请假理由:"+request.getReason());
             System.out.println("小组长:"+name+"审批通过");
         }else {
             if(nextLeader != null){
                 nextLeader.approve(request);
             }
         }
     }
 }
 
 /**
  * 具体处理者角色:部门经理审批
  */
 public class DepartmentManager extends Leader {
 
     public DepartmentManager(String name) {
         super(name);
     }
 
     public void approve(LeaveRequest request) {
         //审批请假天数大于3天小于10天
         if(request.getDay()<=10){
             System.out.println("请假人:"+request.getName()+", 请假天数:"+request.getDay()+", 请假理由:"+request.getReason());
             System.out.println("部门经理:"+name+"审批通过");
         }else {
             if(nextLeader != null){
                 nextLeader.approve(request);
             }
         }
     }
 }
 /**
  * 具体处理者角色:副总经理审批
  */
 public class ViceGeneralManager extends Leader {
 
     public ViceGeneralManager(String name) {
         super(name);
     }
 
     public void approve(LeaveRequest request) {
         /**
          * 审批天数大于10小于20天
          */
         if(request.getDay()<=20){
             System.out.println("请假人:"+request.getName()+", 请假天数:"+request.getDay()+", 请假理由:"+request.getReason());
             System.out.println("副总经理:"+name+"审批通过");
         }else {
             if(nextLeader != null){
                 nextLeader.approve(request);
             }
         }
     }
 }
 
 /**
  * 具体处理者角色:总经理审批
  */
 public class GeneralManager extends Leader {
 
     public GeneralManager(String name) {
         super(name);
     }
 
     public void approve(LeaveRequest request) {
         //审批请假天数大于20天小于30天
         if (request.getDay() <= 30) {
             System.out.println("请假人:" + request.getName() + ", 请假天数:" + request.getDay() + ", 请假理由:" + request.getReason());
             System.out.println("总经理:" + name + "审批通过");
         } else {
             if (nextLeader != null) {
                 nextLeader.approve(request);
             } else {
                 System.out.println("请假人:" + request.getName() + ", 请假天数:" + request.getDay() + ", 请假理由:" + request.getReason());
                 System.out.println("请假天数太长无法审批,请提交请假天数小于30天。");
             }
         }
     }
 }
 

责任链模式客户端测试

 /**
  * 责任链模式客户端测试类
  */
 public class Client {
     public static void main(String[] args) {
         Headman director = new Headman("李大帅");
         DepartmentManager manager = new DepartmentManager("老王");
         ViceGeneralManager viceGeneralManager = new ViceGeneralManager("赵副");
         GeneralManager generalManager = new GeneralManager("胡总");
         director.setNextLeader(manager);
         manager.setNextLeader(viceGeneralManager);
         viceGeneralManager.setNextLeader(generalManager);
 
         LeaveRequest leaveRequest = new LeaveRequest("小王", "感冒了!", 1);
         director.approve(leaveRequest);
         System.out.println("============================================");
         leaveRequest = new LeaveRequest("小李", "加班调休!", 6);
         director.approve(leaveRequest);
         System.out.println("============================================");
         leaveRequest = new LeaveRequest("小胡", "回家探亲!", 12);
         director.approve(leaveRequest);
         System.out.println("============================================");
         leaveRequest = new LeaveRequest("小吴", "回家探亲!", 30);
         director.approve(leaveRequest);
         System.out.println("============================================");
         leaveRequest = new LeaveRequest("小张", "生病休养!", 36);
         director.approve(leaveRequest);
     }
 }
 请假人:小王, 请假天数:1, 请假理由:感冒了!
 小组长:李大帅审批通过
 ============================================
 请假人:小李, 请假天数:6, 请假理由:加班调休!
 部门经理:老王审批通过
 ============================================
 请假人:小胡, 请假天数:12, 请假理由:回家探亲!
 副总经理:赵副审批通过
 ============================================
 请假人:小吴, 请假天数:30, 请假理由:回家探亲!
 总经理:胡总审批通过
 ============================================
 请假人:小张, 请假天数:36, 请假理由:生病休养!
 请假天数太长无法审批,请提交请假天数小于30天。
 
 Process finished with exit code 0
 

小结

本章分享了责任链模式,主要介绍了责任链模式的定义、类图、角色及优缺点,并以请假审批需求为例进行代码实现。

若本文使你受益,还请给予关注、点赞、转发,欢迎拍砖!!!

Tags:

最近发表
标签列表