一、什么是責任鏈模式?
責任鏈模式(Chain of Responsibility Pattern) 是一種行為型設計模式,它讓多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關系。將這些對象連成一條鏈,沿著這條鏈傳遞請求,直到有對象處理它為止。一般用在如下的場景
- 多個對象可以處理同一個請求,但具體由哪個處理方未確定;
- 系統需動態指定處理者;
- 想在運行時靈活地添加新的處理節點;
可能比較抽象,今天本篇就以例子的方式,讓你快速理解到這些文字描述。
二、責任鏈例子
小張想請假,走公司流程:
小張 → 班組長 → 主管 → 部門經理 → 總經理
- 小張請 1 天假,班組長就能批;
- 請 3 天假,需要主管審批;
- 請 7 天,得上總經理簽字。
這就是責任鏈流程。誰能處理就在哪停下,不能處理就往上交。
三、UML結構圖
在這里插入圖片描述
Handler
定義處理請求的接口;- 每個
Leader
具體處理不同級別的請求; - 請求不能處理時,傳給下一個節點。
四、代碼實現
抽象處理者
構建一個抽象的 Handler類。
// 抽象類,定義處理邏輯和下一個節點
public abstract class Handler {protected Handler next;public void setNext(Handler next) {this.next = next;}// 處理請求的方法public abstract void handleRequest(int leaveDays);
}
具體處理者
具體處理審批十各級審批人。
// 班組長處理1天以內的請假
public class TeamLeader extends Handler {@Overridepublic void handleRequest(int leaveDays) {if (leaveDays <= 1) {System.out.println("班組長批準了" + leaveDays + "天的請假");} else if (next != null) {System.out.println("班組長無權處理,轉交主管");next.handleRequest(leaveDays);}}
}
// 主管處理3天以內的請假
public class Supervisor extends Handler {@Overridepublic void handleRequest(int leaveDays) {if (leaveDays <= 3) {System.out.println("主管批準了" + leaveDays + "天的請假");} else if (next != null) {System.out.println("主管無權處理,轉交經理");next.handleRequest(leaveDays);}}
}
// 部門經理處理7天以內的請假
public class Manager extends Handler {@Overridepublic void handleRequest(int leaveDays) {if (leaveDays <= 7) {System.out.println("經理批準了" + leaveDays + "天的請假");} else if (next != null) {System.out.println("經理無權處理,轉交總經理");next.handleRequest(leaveDays);}}
}
// 總經理處理所有請假
public class GeneralManager extends Handler {@Overridepublic void handleRequest(int leaveDays) {System.out.println("總經理批準了" + leaveDays + "天的請假");}
}
構建責任鏈
客戶端調用。
public class Client {public static void main(String[] args) {// 構建鏈條:組長 → 主管 → 經理 → 總經理Handler leader = new TeamLeader();Handler supervisor = new Supervisor();Handler manager = new Manager();Handler generalManager = new GeneralManager();leader.setNext(supervisor);supervisor.setNext(manager);manager.setNext(generalManager);// 發起請求int[] testLeaves = {1, 2, 5, 10};for (int days : testLeaves) {System.out.println("申請" + days + "天請假:");leader.handleRequest(days);System.out.println("------");}}
}
具體輸出
申請1天請假:
班組長批準了1天的請假
------
申請2天請假:
班組長無權處理,轉交主管
主管批準了2天的請假
------
申請5天請假:
班組長無權處理,轉交主管
主管無權處理,轉交經理
經理批準了5天的請假
------
申請10天請假:
班組長無權處理,轉交主管
主管無權處理,轉交經理
經理無權處理,轉交總經理
總經理批準了10天的請假
------
五、鏈式構建器
責任鏈的高級寫法,可以使用鏈式調用簡化鏈條搭建:
leader.setNext(supervisor).setNext(manager).setNext(generalManager);
為此只需修改 setNext()
方法返回值:
public Handler setNext(Handler next) {this.next = next;return next;
}
六、責任鏈模式的優缺點
優點:
- 解耦請求發送者和處理者
- 動態組合鏈條結構,擴展性強
- 處理流程清晰,符合現實邏輯
缺點:
- 可能造成請求無人處理
- 每個處理節點都必須處理轉發邏輯
七、實際應用場景
應用場景 | 描述 |
---|---|
Servlet Filter鏈 | 請求在多個Filter間傳遞 |
Spring Security攔截鏈 | 多個攔截器處理登錄/權限 |
日志記錄 | 日志可傳給不同的輸出設備 |
OA審批流程 | 按審批等級處理請假/報銷等 |
八、小結
責任鏈模式是非常貼近現實的模式之一,很多審批、攔截、處理流程都可以用它來建模。它解耦了處理者與請求者,使系統更靈活、可拓展。掌握此模式,是 Java 工程師進階之路的重要一環。
九、參考
《23種設計模式概覽》
@startuml
title Java責任鏈模式結構圖(Handler責任鏈)abstract class Handler {+setNext(next: Handler)+handleRequest(request)-next: Handler
}class LeaderA {班組長
}
class LeaderB {部門主管
}
class LeaderC {總經理
}
class LeaderN {可以加更多節點......
}Handler <|-- LeaderA
Handler <|-- LeaderB
Handler <|-- LeaderCHandler <|-- "LeaderN"@enduml