責任鏈,顧名思義,就是用來處理相關事務責任的一條執行鏈,執行鏈上有多個節點,每一個節點都有機會(條件匹配)處理請求事務,若是某個節點處理完了就能夠根據實際業務需求傳遞給下一個節點繼續處理或者返回處理完畢。java
現實中,請假的OA申請,請假天數若是是半天到1天,可能直接主管批准便可; 若是是1到3天的假期,須要部門經理批准; 若是是3天到30天,則須要總經理審批; 大於30天,正常不會批准。設計模式
爲了實現上述場景,咱們能夠採用責任鏈設計模式。ide
員工請求發起申請到抽象的責任處理類中,根據員工的請假天數,對應的處理類完成處理。 每個責任處理類設置下面的節點。自身處理不了則傳遞給下一個節點處理。ui
LeaveRequest.java:this
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class LeaveRequest {
/**天數*/
private int leaveDays;
/**姓名*/
private String name;
}
複製代碼
AbstractLeaveHandler.jav;spa
/** * @program: cookbook * @description: 請假責任鏈抽象處理類 * @author: Byron * @create: 2019/07/11 09:34 */
public 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.jav:設計
/** * @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:3d
/** * @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.MIN && 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.MIDDLE && request.getLeaveDays() <= this.MAX){
System.out.println("總經理:" + handlerName + ",已經處理;流程結束。");
return;
}
if(null != this.nextHandler){
this.nextHandler.handlerRequest(request);
}else{
System.out.println("審批拒絕!");
}
}
}
複製代碼
ResponsibilityTest.java:code
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);
}
}
複製代碼
責任鏈主要重在責任分離處理,讓各個節點各司其職。 責任鏈上的各個節點都有機會處理事務,可是也可能不會受理請求。 責任鏈比較長,調試時可能會比較麻煩。 責任鏈通常用於處理流程節點之類的實際業務場景中。 Spring攔截器鏈、servlet過濾器鏈等都採用了責任鏈設計模式。