責任鏈 (Chain of Responsibility)

★★★★Studied

FromDesign Patterns (GoF)大話設計模式

📚 From the Books

責任鏈 (Chain of Responsibility)ConceptBehavioral

把一個請求沿著「處理者鏈」往下傳,每個處理者自己決定要當場處理,還是丟給下一棒。發送者不必知道誰會處理、處理幾次,發送端與接收端因此解耦。

🧠 When to Use

TIP

訊號:同一個請求「可能由多個對象之一」處理,而你正想寫一串 if (canA) ... else if (canB) ... 來決定誰接手。

⚖️ Structure & Variants

經典版 — 鏈結節點,逐棒往下傳
abstract class Approver(private val next: Approver?) {
    fun handle(amount: Int) {
        if (canApprove(amount)) approve(amount)
        else next?.handle(amount)            // ← 自己處理不了就往下傳
    }
    protected abstract fun canApprove(amount: Int): Boolean
    protected abstract fun approve(amount: Int)
}

class Manager(next: Approver?) : Approver(next) {
    override fun canApprove(a: Int) = a <= 10_000
    override fun approve(a: Int) = println("Manager approves $a")
}

val chain = Manager(/* next = */ Director(null))
chain.handle(5_000)    // Manager 接手
  • chain.handle 的呼叫端不知道是誰批准的,也不需要知道鏈有多長。
Pipeline 版 — middleware 串接(攔截過濾器)
  • Web 框架的 middleware/filter 鏈是同構:每一段拿到 request 和「下一棒 next」,可前處理、可呼叫 next()、可短路。
  • 和經典版差別:每段通常都會呼叫下一棒(過濾器鏈),而非「處理完就停」。
和 Decorator 的差別(結構都是串起來)
  • Chain:每個節點可以「決定不往下傳」而中斷請求,重點在「誰處理」。
  • Decorator:每層都會呼叫被包裹者,重點在「層層疊加行為」,不會吞掉請求。

⚠️ Misuse & Anti-patterns

🔑 Takeaways

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading