設計模式之責任鏈模式


什么是責任鏈模式?


在現實生活中,有很多請求並不是一個人說了就算的,例如面試時的工資,低於1萬的薪水可能技術經理就可以決定了,但是1萬~1萬5的薪水可能技術經理就沒這個權利批准,可能就需要請求技術總監的批准,所以在面試的完后,經常會有面試官說,你這個薪水我這邊覺得你這技術可以拿這個薪水的,但是還需要技術總監的批准等的話。

責任鏈模式——某個請求需要多個對象進行處理,從而避免請求的發送者和接收之間的耦合關系。將這些對象連成一條鏈子,並沿着這條鏈子傳遞該請求,直到有對象處理它為止。主要涉及兩個角色:

  • 抽象處理者角色(Handler):定義出一個處理請求的接口。這個接口通常由接口或抽象類來實現。
  • 具體處理者角色(ConcreteHandler):具體處理者接受到請求后,可以選擇將該請求處理掉,或者將請求傳給下一個處理者。因此,每個具體處理者需要保存下一個處理者的引用,以便把請求傳遞下去。

設計思路及代碼實現

/// <summary>
/// 采購請求
/// </summary>
public class PurchaseRequest
{
    public double Amount { get; set; }

    public string ProductName { get; set; }

    public PurchaseRequest(string productName, double amount)
    {
        this.ProductName = productName;
        this.Amount = amount;
    }
}

/// <summary>
/// 審批人
/// </summary>
public abstract class Approver
{
    public Approver NextApprover { get; set; }

    public string Name { get; set; }

    public abstract void ProcessRequest(PurchaseRequest request);

    public Approver(string name)
    {
        Name = name;
    }
}

/// <summary>
/// 小頭頭
/// </summary>
public class Manager : Approver
{
    public Manager(string name)
        : base(name)
    {
    }

    public override void ProcessRequest(PurchaseRequest request)
    {
        if (request.Amount < 10000)
        {
            Console.WriteLine("{0}-{1} approved the request of purshing {2}", this.GetType().Name, Name, request.ProductName);
        }
        else if (NextApprover != null)
        {
            NextApprover.ProcessRequest(request);
        }
    }
}

/// <summary>
/// 副總經理
/// </summary>
public class VicePresident : Approver
{
    public VicePresident(string name) 
        : base(name)
    {
    }

    public override void ProcessRequest(PurchaseRequest request)
    {
        if (request.Amount < 50000)
        {
            Console.WriteLine("{0}-{1} approved the request of purshing {2}", this.GetType().Name, Name, request.ProductName);
        }
        else if (NextApprover != null)
        {
            NextApprover.ProcessRequest(request);
        }
    }
}

/// <summary>
/// 總經理
/// </summary>
public class President : Approver
{
    public President(string name) 
        : base(name)
    {
    }

    public override void ProcessRequest(PurchaseRequest request)
    {
        if (request.Amount < 100000)
        {
            Console.WriteLine("{0}-{1} approved the request of purshing {2}", this.GetType().Name, Name, request.ProductName);
        }
        else if (NextApprover != null)
        {
            NextApprover.ProcessRequest(request);
        }
    }
}

責任鏈模式的優缺點

優點:

  • 降低了請求的發送者和接收者之間的耦合。
  • 把多個條件判定分散到各個處理類中,使得代碼更加清晰,責任更加明確。

缺點:

  • 在找到正確的處理對象之前,所有的條件判定都要執行一遍,當責任鏈過長時,可能會引起性能的問題
  • 可能導致某個請求不被處理。

責任鏈模式的適用場景

在以下場景中可以考慮使用責任鏈模式:

  • 一個系統的審批需要多個對象才能完成處理的情況下,例如請假系統等。
  • 代碼中存在多個if-else語句的情況下,此時可以考慮使用責任鏈模式來對代碼進行重構。

代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM