🎯 什麼情境該想到我
當你「有一個請求,可能由好幾個物件之一來處理,但事前不確定誰該處理、想讓執行期沿著一條鏈自動找到合適的處理者」的時候(例如逐級審批、事件冒泡、web 的 middleware/攔截器)。
⚙️ 怎麼用(步驟 / 公式)
意圖:讓多個物件都有機會處理請求,藉此避免把發送者與接收者綁死。把這些物件串成一條鏈,請求沿鏈傳遞,直到有物件處理它為止。
主要參與者 / 結構:
- Handler(處理者介面):定義處理請求的介面,通常持有一個指向「下一個處理者」的參照。
- ConcreteHandler(具體處理者):判斷自己能否處理;能就處理,否則轉交給下一個。
- Client:把請求丟給鏈的第一個處理者,不需知道最後是誰處理的。
做法要點:
- 定義 Handler 介面,內含
handle(request)與一個next後繼參照。 - 每個具體處理者收到請求後,先判斷是否屬於自己職責:是就處理(可選擇是否繼續往下傳),否則呼叫
next.handle(request)。 - 由外部把處理者依序串接成鏈,Client 只認得鏈頭。
- 鏈的組成與順序可在執行期動態調整。
🧪 我實際套用的紀錄
- (待填)
⚠️ 注意 / 什麼時候不適用
- 不保證請求一定被處理:可能一路傳到鏈尾都沒有人接,需自行設計「沒人處理」的收尾。
- 鏈太長會拖累效能,且「請求到底是誰處理的」不易追蹤,除錯較麻煩。
- 若請求與處理者是固定的一對一關係,直接呼叫即可,套鏈只是多繞路。
🔗 相關工具
- 命令模式 Command(常把沿鏈傳遞的請求封裝成命令物件)
- 組合模式 Composite(樹狀結構中把請求沿父節點上傳,天生就是一條責任鏈)
- 中介者模式 Mediator(同樣想降低物件間耦合,但中介者集中轉發、責任鏈是逐個接力)
- 工具-針對介面編程(Client 與各處理者只依賴 Handler 介面)
- 工具-封裝變化點(把「由誰處理、順序如何」這個變化點封裝在鏈的組裝裡)
- 設計模式