首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 責任鏈模式深度解析:動態組織處理者鏈路與請求傳遞機制

     編輯:關於C#

前言

當一個請求可能由多個處理者處理,但發送者不明確知道由誰處理,且處理者集合動態變化時,責任鏈模式提供優雅方案:將處理者串成一條鏈,請求沿鏈傳遞,直到有處理者處理它或到達鏈尾。這避免了發送者與接收者的強耦合,且支援動態新增/移除/重排處理者。本文以「根據訊息長度分級審批」(員工<5字、主管<10字、經理<15字)為例,完整展示責任鏈模式的鏈路構建、請求傳遞與終止機制。

模式結構與三大角色

  • Handler(抽象處理者):AbstractExecutor,定義 SetSuccessor() 設定下一級、Insert(MessageModel) 處理請求介面,內含 _executor 參考指向下一級。
  • ConcreteHandler(具體處理者):Employee、Leader、Manager,各自實作處理條件與邏輯,若不滿足條件則呼叫 _executor.Insert() 傳遞給下一級。
  • Client(客戶端):建立處理者實例,透過 SetSuccessor() 組裝鏈路順序,發起請求給鏈頭。
責任鏈模式類別圖

核心程式碼機制深度解析

1. 抽象處理者:鏈路連結與介面定義

public abstract class AbstractExecutor
{
    protected AbstractExecutor _executor; // 下一級處理者

    public void SetSuccessor(AbstractExecutor executor)
    {
        this._executor = executor;
    }

    public abstract string Insert(MessageModel mm);
}

關鍵點:_executor 為 protected 允許子類別存取,SetSuccessor() 提供外部組裝鏈路的介面。

2. 具體處理者:條件判斷與傳遞邏輯

Employee(員工):處理長度 < 5 字

public class Employee : AbstractExecutor
{
    public override string Insert(MessageModel mm)
    {
        string rtn = "";
        if (mm.Message.Length < 5)
        {
            SqlMessage m = new SqlMessage();
            if (m.Insert(mm))
                rtn = "執行者:雇員 內容:" + mm.Message + " 時間:" + mm.PublishTime;
        }
        else if (base._executor != null)
            rtn = _executor.Insert(mm); // 傳遞下一級
        return rtn;
    }
}

Leader(主管):處理長度 < 10 字

public class Leader : AbstractExecutor
{
    public override string Insert(MessageModel mm)
    {
        string rtn = "";
        if (mm.Message.Length < 10)
        {
            SqlMessage m = new SqlMessage();
            if (m.Insert(mm))
                rtn = "執行者:主管 內容:" + mm.Message + " 時間:" + mm.PublishTime;
        }
        else if (base._executor != null)
            rtn = _executor.Insert(mm);
        return rtn;
    }
}

Manager(經理):處理長度 < 15 字,鏈尾處理失敗情況

public class Manager : AbstractExecutor
{
    public override string Insert(MessageModel mm)
    {
        string rtn = "";
        if (mm.Message.Length < 15)
        {
            SqlMessage m = new SqlMessage();
            if (m.Insert(mm))
                rtn = "執行者:經理 內容:" + mm.Message + " 時間:" + mm.PublishTime;
        }
        else
            rtn = "你所插入的Message不符合要求"; // 鏈尾終止
        return rtn;
    }
}

3. 客戶端:鏈路組裝與請求發起


AbstractExecutor employee = new Employee();
AbstractExecutor leader = new Leader();
AbstractExecutor manager = new Manager();

employee.SetSuccessor(leader); // 員工 → 主管
leader.SetSuccessor(manager);  // 主管 → 經理

// 發起請求給鏈頭
Response.Write(employee.Insert(new MessageModel("abcd", Now)));       // 4字 → 員工
Response.Write(employee.Insert(new MessageModel("abcdefgh", Now)));   // 8字 → 主管
Response.Write(employee.Insert(new MessageModel("abcdefghigkl", Now))); // 12字 → 經理
Response.Write(employee.Insert(new MessageModel("abcdefghigklmnop", Now))); // 16字 → 拒絕

執行結果驗證

執行者:雇員 內容:abcd 時間:2007-4-22 20:04:41
執行者:主管 內容:abcdefgh 時間:2007-4-22 20:04:41
執行者:經理 內容:abcdefghigkl 時間:2007-4-22 20:04:41
你所插入的Message不符合要求

完美驗證:請求沿鏈傳遞,首個滿足條件的處理者處理並終止傳遞,超出範圍由鏈尾拒絕。

進階變體與設計考量

純責任鏈 vs 不純責任鏈

  • 純責任鏈:每個處理者要么完全處理要么完全傳遞,不允許部分處理後再傳遞。本範例屬此類。
  • 不純責任鏈:處理者可先處理部分邏輯(如日誌、驗證),再傳遞給下一級(如 ASP.NET Core Middleware 管道)。

鏈路動態構建策略

  • 客戶端手動組裝:如本範例,靈活但需客戶端知曉所有處理者。
  • 建造者模式:ChainBuilder 封裝組裝邏輯,支援流式 API:builder.Add().Add().Add().Build()。
  • 依賴注入容器:註冊處理者集合,啟動時按順序自動串聯(如 IEnumerable<IHandler> 注入)。
  • 屬性/配置驅動:處理者標註 [HandlerOrder(1)],框架自動排序組裝。

避免無限遞迴與死循環

  • 確保鏈路無環:SetSuccessor() 檢測是否已在鏈中。
  • 設定最大傳遞深度或超時機制。
  • 鏈尾預設處理者(NullHandler)避免空參考。

與中介者模式對比

維度責任鏈中介者
結構線性鏈路星狀中心化
耦合處理者只知下一級同事只知中介者
決策分散在各處理者集中在中介者
適用順序處理、條件分發複雜多對多協調

優缺點總結

優點

  • 發送者與接收者解耦:發送者只知鏈頭。
  • 動態調整鏈路:執行時新增/移除/重排處理者。
  • 單一職責:每個處理者專注特定條件/邏輯。
  • 開閉原則:新增處理者無需修改既有程式碼。

缺點

  • 請求可能不被處理(鏈尾無處理者),需明確處理預設情況。
  • 長鏈路效能開銷(O(n) 遍歷),可用快取/索引優化。
  • 除錯困難:請求流經多個物件,堆疊追蹤較複雜。
  • 循環引用風險:組裝邏輯錯誤導致死循環。

經典應用場景

  • Web 框架中介軟體管道:ASP.NET Core UseMiddleware、Express.js app.use()。
  • 權限審批流程:員工→主管→經理→總監,金額/風險分級。
  • 事件處理:DOM 事件冒泡、WPF 路由事件。
  • 日誌框架:Logger 鏈(Console→File→Database→Remote)。
  • 資料驗證管道:Required→Length→Format→BusinessRule。

總結

責任鏈模式以「鏈路傳遞」取代「條件分發」,將處理邏輯分散至獨立處理者,實現發送者與接收者的解耦與動態組合。本範例以訊息長度分級審批為例,完整展示了抽象處理者定義鏈路結構、具體處理者實作條件判斷與傳遞、客戶端組裝鏈路順序的全流程。實務中,ASP.NET Core Middleware、Java Servlet Filter、Log4j Appender 皆為責任鏈模式的經典應用。掌握此模式,能讓你在設計「多階段處理管道、條件分發路由、插件化擴展點」時,構建出靈活可組合、易於維護擴展的系統架構。


參考資源:DoFactory Chain of Responsibility

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved