【設計模式】責任鏈模式

責任鏈模式

概念描述

責任鏈,顧名思義,就是用來處理相關事務責任的一條執行鏈,執行鏈上有多個節點,每一個節點都有機會(條件匹配)處理請求事務,若是某個節點處理完了就能夠根據實際業務需求傳遞給下一個節點繼續處理或者返回處理完畢。java

適用場景

現實中,請假的OA申請,請假天數若是是半天到1天,可能直接主管批准便可;
若是是1到3天的假期,須要部門經理批准;
若是是3天到30天,則須要總經理審批;
大於30天,正常不會批准。git

流程展現

流程展現

類圖設計

爲了實現上述場景,咱們能夠採用責任鏈設計模式。github

  • 員工提交請求類:LeaveRequest。
  • 抽象的請假責任處理類:AbstractLeaveHandler。
  • 直接主管審批處理類:DirectLeaderLeaveHandler。
  • 部門經理處理類:DeptManagerLeaveHandler。
  • 總經理處理類: GManagerLeaveHandler。

員工請求發起申請到抽象的責任處理類中,根據員工的請假天數,對應的處理類完成處理。
每個責任處理類設置下面的節點。自身處理不了則傳遞給下一個節點處理。編程

類圖

編程實現

LeaveRequest.java:

@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class LeaveRequest {
    /**天數*/
    private int leaveDays;

    /**姓名*/
    private String name;
}

AbstractLeaveHandler.java;

/**
 * @program: cookbook
 * @description: 請假責任鏈抽象處理類
 * @author: Byron
 * @create: 2019/07/11 09:34
 */
public abstract class AbstractLeaveHandler {
    /**直接主管審批處理的請假天數*/
    protected int MIN = 1;
    /**部門經理處理的請假天數*/
    protected int MIDDLE = 3;
    /**總經理處理的請假天數*/
    protected int MAX = 30;

    /**領導名稱*/
    protected String handlerName;

    /**下一個處理節點(即更高級別的領導)*/
    protected AbstractLeaveHandler nextHandler;

    /**設置下一節點*/
    protected void setNextHandler(AbstractLeaveHandler handler){
        this.nextHandler = handler;
    }

    /**處理請假的請求,子類實現*/
    protected void handlerRequest(LeaveRequest request){

    }


}

DirectLeaderLeaveHandler.java:

/**
 * @program: cookbook
 * @description: 直接主管處理類
 * @author: Byron
 * @create: 2019/07/11 09:46
 */
public class DirectLeaderLeaveHandler extends AbstractLeaveHandler{
    public DirectLeaderLeaveHandler(String name) {
        this.handlerName = name;
    }

    @Override
    protected void handlerRequest(LeaveRequest request) {
        if(request.getLeaveDays() <= this.MIN){
            System.out.println("直接主管:" + handlerName + ",已經處理;流程結束。");
            return;
        }

        if(null != this.nextHandler){
            this.nextHandler.handlerRequest(request);
        }else{
            System.out.println("審批拒絕!");
        }

    }
}

DeptManagerLeaveHandler.java:

/**
 * @program: cookbook
 * @description: 部門經理處理類
 * @author: Byron
 * @create: 2019/07/11 09:48
 */
public class DeptManagerLeaveHandler extends AbstractLeaveHandler {

    public DeptManagerLeaveHandler(String name) {
        this.handlerName = name;
    }

    @Override
    protected void handlerRequest(LeaveRequest request) {
        if(request.getLeaveDays() <= this.MIDDLE){
            System.out.println("部門經理:" + handlerName + ",已經處理;流程結束。");
            return;
        }

        if(null != this.nextHandler){
            this.nextHandler.handlerRequest(request);
        }else{
            System.out.println("審批拒絕!");
        }
    }
}

GManagerLeaveHandler.java:

/**
 * @program: cookbook
 * @description: 總經理處理類
 * @author: Byron
 * @create: 2019/07/11 09:49
 */
public class GManagerLeaveHandler extends AbstractLeaveHandler {
    public GManagerLeaveHandler(String name) {
        this.handlerName = name;
    }

    @Override
    protected void handlerRequest(LeaveRequest request) {
        if(request.getLeaveDays() <= this.MAX){
            System.out.println("總經理:" + handlerName + ",已經處理;流程結束。");
            return;
        }

        if(null != this.nextHandler){
            this.nextHandler.handlerRequest(request);
        }else{
            System.out.println("審批拒絕!");
        }
    }
}

演示

ResponsibilityTest.java:

public class ResponsibilityTest {
    public static void main(String[] args) {
        LeaveRequest request = LeaveRequest.builder().leaveDays(20).name("小明").build();


        AbstractLeaveHandler directLeaderLeaveHandler = new DirectLeaderLeaveHandler("縣令");
        DeptManagerLeaveHandler deptManagerLeaveHandler = new DeptManagerLeaveHandler("知府");
        GManagerLeaveHandler gManagerLeaveHandler = new GManagerLeaveHandler("京兆尹");

        directLeaderLeaveHandler.setNextHandler(deptManagerLeaveHandler);
        deptManagerLeaveHandler.setNextHandler(gManagerLeaveHandler);

        directLeaderLeaveHandler.handlerRequest(request);


    }
}
  • 20天,運行輸出: 總經理:京兆尹,已經處理;流程結束。
  • 1天,運行輸出: 直接主管:縣令,已經處理;流程結束。
  • 3天,運行輸出: 部門經理:知府,已經處理;流程結束。
  • 35天,運行輸出: 審批拒絕!

總結

  • 責任鏈主要重在責任分離處理,讓各個節點各司其職。
  • 責任鏈上的各個節點都有機會處理事務,可是也可能不會受理請求。
  • 責任鏈比較長,調試時可能會比較麻煩。
  • 責任鏈通常用於處理流程節點之類的實際業務場景中。
  • Spring攔截器鏈、servlet過濾器鏈等都採用了責任鏈設計模式。

連接

相關文章
相關標籤/搜索