責任鏈模式將多個處理者對象鏈接成鏈,請求沿鏈傳遞,直到某處理者處理為止。核心價值:
| 角色 | 職責 | 代碼體現 |
|---|---|---|
| Handler(抽象處理者) | 定義處理接口、持有後繼者引用 | interface / abstract class |
| ConcreteHandler(具體處理者) | 實現具體邏輯,決定:處理 / 轉發 / 兩者兼有 | 實現類 |
| Client(客戶端) | 組裝鏈、發起請求 | 構建鏈、調用 head.handle() |
系統需生成員工工號、檔案代號等,規則包含年份、月份、日期、流水號等可變元素,且未來可能擴展新元素。
// 違反開閉原則,新增元素需修改核心邏輯
public String[] generateCode(String rule) {
if (rule.contains("YYYY")) { /* 年份邏輯 */ }
if (rule.contains("MM")) { /* 月份邏輯 */ }
// ... 越來越長、難維護
}
// 1. 統一處理接口
public interface CodeAutoParse {
String[] generateCode(String moduleCode, int number, String rule, String[] target) throws BaseException;
}
// 2. 日期處理器
@Component
public class DateAutoParse implements CodeAutoParse {
private final Calendar currentDate = Calendar.getInstance();
@Autowired(required = false) // 可選後繼者
private CodeAutoParse nextParse;
public String[] generateCode(String moduleCode, int number, String rule, String[] target) throws BaseException {
// 解析規則中的日期佔位符(YYYY, MM, DD 等)
// ... 業務邏輯省略
return (nextParse != null) ? nextParse.generateCode(moduleCode, number, rule, target) : target;
}
}
// 3. 流水號處理器
@Component
public class SequenceAutoParse implements CodeAutoParse {
@Autowired(required = false)
private CodeAutoParse nextParse;
// ... 類似結構
}
// 4. Spring 配置鏈順序(applicationContext.xml 或 @Order)
/*
<bean id="dateParse" class="com.example.DateAutoParse">
<property name="nextParse" ref="sequenceParse"/>
</bean>
<bean id="sequenceParse" class="com.example.SequenceAutoParse">
<property name="nextParse" ref="customParse"/>
</bean>
*/
CodeAutoParse 接口public boolean action(Event event, Object obj) {
if (event.target == btnOK) { doOKBtnAction(); }
else if (event.target == btnExit) { doExitBtnAction(); }
else { return super.action(event, obj); } // 向父容器傳播
return true; // true = 停止傳播,false = 繼續傳播
}
| 優點 | 缺點 |
|---|---|
| 降低耦合:發送者/接收者互不知曉 | 性能開銷:請求需遍歷鏈(可通過鏈長度控制、優先級優化) |
| 動態靈活:運行時增刪/調序處理者 | 調試困難:調用鏈隱式,日誌需記錄鏈路信息 |
| 單一職責:每類邏輯獨立封裝 | 遞歸深度:極長鏈可能導致 StackOverflow |
責任鏈模式不是「鏈表數據結構」的同義詞,而是「職責分發」的架構思想。在 Java 中配合 Spring 依賴注入管理鏈路組裝,能將業務規則變更點隔離在單獨 Handler 中,實現「對擴展開放,對修改關閉」。無論純與不純,關鍵在於:識別系統中「可變的處理邏輯」,將其封裝為獨立 Handler,通過配置而非代碼修改來組合行為。