23_責任鏈模式

野码發表於2024-03-17

責任鏈模式是一種行為設計模式,它可以將請求的傳送者和接收者解耦,並且允許多個物件都有機會處理請求。

在責任鏈模式中,每個處理者都持有對下一個處理者的引用,形成一個鏈條。當請求發出時,從鏈條的頭部開始,每個處理者都有機會處理請求。如果某個處理者能夠處理請求,它就會處理請求並結束,否則將請求傳遞給下一個處理者,直到有一個處理者能夠處理請求或者到達鏈條的末尾。

責任鏈模式包含以下幾個角色:

  1. 抽象處理者(Handler):定義了處理請求的介面,並持有對下一個處理者的引用。

  2. 具體處理者(Concrete Handler):實現了處理請求的方法,並決定是否能夠處理請求。

責任鏈模式的工作流程如下:

  1. 建立具體處理者物件,並確定它們的處理順序。

  2. 將具體處理者按照順序連線成一條鏈。

  3. 傳送請求給鏈條的頭部處理者。

  4. 頭部處理者根據自己的邏輯判斷是否能夠處理請求,如果能夠處理,則處理請求並結束;如果不能處理,則將請求傳遞給下一個處理者。

  5. 重複步驟4,直到有一個處理者能夠處理請求或者到達鏈條的末尾。

責任鏈模式的優點包括:

  1. 解耦了請求的傳送者和接收者,使得系統更加靈活和可擴充套件。

  2. 可以動態地新增、修改和刪除處理者,靈活地調整處理鏈的結構。

  3. 可以避免請求的傳送者和接收者之間的耦合,使系統更加符合單一職責原則。

責任鏈模式適用於以下情況:

  1. 有多個物件可以處理請求,但是不確定哪個物件能夠處理請求,或者可以處理請求的物件會隨著時間的推移而改變。

  2. 需要在不同的物件之間動態地傳遞請求。

  3. 需要將請求的傳送者和接收者解耦,提高系統的靈活性和可擴充套件性。

總之,責任鏈模式是一種將請求的傳送者和接收者解耦的設計模式,它可以形成一個處理鏈條,每個處理者都有機會處理請求。這種模式可以提高系統的靈活性和可擴充套件性,適用於處理複雜的請求邏輯。

案例場景:訂單稽核,經理,總監,副總裁

/// <summary>
    /// 需要處理的請求,需要稽核的訂單
    /// 經理<=5000,總監<=10000,副總裁<=50000
    /// </summary>
    public class Order
    {
        public int Id { get; set; }
        public string Name { get; set; }
        /// <summary>
        /// 金額
        /// </summary>
        public int Amount { get; set; }
    }

Handler

/// <summary>
    /// 抽象處理器
    /// </summary>
    public abstract class HandlerBase
    {
        /// <summary>
        /// 是否同意
        /// </summary>
        /// <param name="order"></param>
        public abstract void Approve(Order order);

        /// <summary>
        /// 下一個簽字人
        /// </summary>
        public HandlerBase NextHandler { get;private  set; }

        /// <summary>
        /// 設定下一個簽字人
        /// </summary>
        /// <param name="nextHandler"></param>
        public virtual void SetNextHandler(HandlerBase nextHandler)
        {
            NextHandler = nextHandler;
        }
    }

Concrete Handler

/// <summary>
    /// 經理
    /// </summary>
    public class Manager : HandlerBase
    {
        public override void Approve(Order order)
        {
            if(order!=null)
            {
                if(order.Amount<=5000)
                {
                    Console.WriteLine("經理稽核成功");
                }
                else
                {
                    if(NextHandler!=null)
                    {
                        NextHandler.Approve(order);
                    }
                    else
                    {
                        Console.WriteLine("稽核不存在");
                    }
                }
            }
            else
            {
                throw new Exception("訂單不能為空");
            }
        }
    }
/// <summary>
    /// 總監
    /// </summary>
    public class Director : HandlerBase
    {
        public override void Approve(Order order)
        {
            if (order != null)
            {
                if (order.Amount <= 10000)
                {
                    Console.WriteLine("總監稽核成功");
                }
                else
                {
                    if (NextHandler != null)
                    {
                        NextHandler.Approve(order);
                    }
                    else
                    {
                        Console.WriteLine("稽核不存在");
                    }
                }
            }
            else
            {
                throw new Exception("訂單不能為空");
            }
        }
    }
/// <summary>
    /// 副總裁
    /// </summary>
    public class VicePresident : HandlerBase
    {
        public override void Approve(Order order)
        {
            if (order != null)
            {
                if (order.Amount <= 50000)
                {
                    Console.WriteLine("副總裁稽核成功");
                }
                else
                {
                    Console.WriteLine("CEO稽核");
                }
            }
            else
            {
                throw new Exception("訂單不能為空");
            }
        }
    }

呼叫

internal class Client
    {
        public void Start()
        {
            HandlerBase manager = new Manager();
            HandlerBase director=new Director();
            HandlerBase vicePresident= new VicePresident();

            manager.SetNextHandler(director);
            director.SetNextHandler(vicePresident);

            Order order = new Order()
            {
                Id = 1,
                Name = "張三",
                Amount = 52000
            };
            manager.Approve(order);
        }
    }
static void Main(string[] args)
        {
            new Client().Start();
            Console.ReadKey();
            Console.WriteLine("Hello, World!");
        }

相關文章