定義
????????Chain of Responsibility Pattern:使多個對象都有機會處理請求,從而避免了請求的發送者和接受者之間的耦合關系。將這些對象連成一條鏈, 并沿著這條鏈傳遞該請求,直到有對象處理它為止。
優勢
-
解耦請求發送者與接收者,發送者無需知道具體由哪個對象處理請求;
-
新增處理者時只需加入鏈條,無需修改原有代碼,符合 “開閉原則”。
場景
生活場景
最典型的例子是?公司請假審批流程:
-
請假 1 天以內:組長直接審批;
-
請假 1-3 天:組長無權處理,傳遞給部門經理審批;
-
請假 3 天以上:部門經理無權處理,傳遞給總經理審批。
這里,組長→部門經理→總經理形成一條 “責任鏈”,請假請求會沿著鏈條傳遞,直到被對應的負責人處理。
Java 中的責任鏈場景
-
Servlet Filter 鏈:
客戶端請求經過多個 Filter(過濾器)處理(如編碼過濾、權限校驗、日志記錄等),每個 Filter 可選擇處理請求后傳遞給下一個 Filter,或直接終止請求。 -
Spring Interceptor 鏈:
Spring MVC 中的攔截器鏈,對請求進行預處理(如登錄驗證)、后處理(如數據封裝),每個 Interceptor 可決定是否繼續傳遞請求。 -
異常處理機制:
Java 的異常捕獲(try-catch)本質上也是責任鏈:異常會從發生處向上傳遞,直到被第一個匹配的 catch 塊處理。
代碼
// 抽象審批者類:定義責任鏈節點的通用行為
abstract class Approver {protected Approver nextApprover; // 下一個審批者(責任鏈的下一個節點)// 設置下一個審批者public void setNextApprover(Approver nextApprover) {this.nextApprover = nextApprover;}// 抽象處理方法:子類需實現具體審批邏輯public abstract void handleRequest(LeaveRequest request);
}// 請假請求類:封裝請求信息class LeaveRequest {private String name; // 申請人姓名private int days; // 請假天數public LeaveRequest(String name, int days) {this.name = name;this.days = days;}// getter方法public String getName() {return name;}public int getDays() {return days;}
}// 組長:處理1天以內的請假class GroupLeader extends Approver {@Overridepublic void handleRequest(LeaveRequest request) {if (request.getDays() <= 1) {System.out.println("組長批準 " + request.getName() + " 請假" + request.getDays() + "天");} else {// 超過權限,傳遞給下一個審批者if (nextApprover != null) {nextApprover.handleRequest(request);}}}
}// 總經理:處理3天以上的請假
class GeneralManager extends Approver {@Overridepublic void handleRequest(LeaveRequest request) {if (request.getDays() > 3) {System.out.println("總經理批準 " + request.getName() + " 請假" + request.getDays() + "天");} else {// 超過權限,傳遞給下一個審批者(此處為鏈的終點,可省略)if (nextApprover != null) {nextApprover.handleRequest(request);}}}
}// 部門經理:處理1-3天的請假class DeptManager extends Approver {@Overridepublic void handleRequest(LeaveRequest request) {if (request.getDays() > 1 && request.getDays() <= 3) {System.out.println("部門經理批準 " + request.getName() + " 請假" + request.getDays() + "天");} else {// 超過權限,傳遞給下一個審批者if (nextApprover != null) {nextApprover.handleRequest(request);}}}
}// 測試類:構建責任鏈并模擬請假請求
class Client {public static void main(String[] args) {// 創建審批者Approver groupLeader = new GroupLeader();Approver deptManager = new DeptManager();Approver generalManager = new GeneralManager();// 構建責任鏈:組長→部門經理→總經理groupLeader.setNextApprover(deptManager);deptManager.setNextApprover(generalManager);// 模擬請假請求LeaveRequest request1 = new LeaveRequest("張三", 1); // 1天:組長處理LeaveRequest request2 = new LeaveRequest("李四", 2); // 2天:部門經理處理LeaveRequest request3 = new LeaveRequest("王五", 5); // 5天:總經理處理// 發送請求(從鏈的起點開始)groupLeader.handleRequest(request1);groupLeader.handleRequest(request2);groupLeader.handleRequest(request3);}
}
責任鏈模式代碼