1. 程式人生 > >設計模式(13)責任鏈模式

設計模式(13)責任鏈模式

模式介紹

責任鏈設計模式試圖通過給不止一個物件處理特定請求的機會,來避免將請求耦合到特定接收器。
本質上,我們沿著該物件的潛在處理程式的“鏈”傳遞物件,直到其中一個處理程式處理請求。

示例

我們還是以餐館建模。
想一下,當廚房需要採購新裝置,廚師長需要像Boss請示。

我們的店裡的採購流程是這樣的:

  1. 1000元以內,廚師長自己就可以做決定
  2. 1000-2500元,必須報採購經理審批
  3. 2500-10000元,必須報總經理審批
  4. 超過10000元,總經理需要開個會議決定了

我們可以看得出來層級結構:廚師長-->採購經理-->總經理
下面我們就使用該模式進行採購系統的實現:

採購單:

/// <summary>
/// The details of the purchase request.  
/// </summary>
class PurchaseOrder
{

    // Constructor
    public PurchaseOrder(int number, double amount, double price, string name)
    {
        RequestNumber = number;
        Amount = amount;
        Price = price;
        Name = name;

        Console.WriteLine("Purchase request for " + name + " (" + amount + " for $" + price.ToString() + ") has been submitted.");
    }

    public int RequestNumber { get; set; }
    public double Amount { get; set; }
    public double Price { get; set; }
    public string Name { get; set; }
}

批准人(抽象類):

/// <summary>
/// The Handler abstract class.  Every class which inherits from this will be responsible for a kind of request for the restaurant.
/// </summary>
abstract class Approver
{
    protected Approver Supervisor;

    public void SetSupervisor(Approver supervisor)
    {
        this.Supervisor = supervisor;
    }

    public abstract void ProcessRequest(PurchaseOrder purchase);
}

具體的批准人:

/// <summary>
/// A concrete Handler class
/// </summary>
class HeadChef : Approver
{
    public override void ProcessRequest(PurchaseOrder purchase)
    {
        if (purchase.Price < 1000)
        {
            Console.WriteLine("{0} approved purchase request #{1}",
                this.GetType().Name, purchase.RequestNumber);
        }
        else if (Supervisor != null)
        {
            Supervisor.ProcessRequest(purchase);
        }
    }
}

/// <summary>
/// A concrete Handler class
/// </summary>
class PurchasingManager : Approver
{
    public override void ProcessRequest(PurchaseOrder purchase)
    {
        if (purchase.Price < 2500)
        {
            Console.WriteLine("{0} approved purchase request #{1}",
                this.GetType().Name, purchase.RequestNumber);
        }
        else if (Supervisor != null)
        {
            Supervisor.ProcessRequest(purchase);
        }
    }
}

/// <summary>
/// A concrete Handler class
/// </summary>
class GeneralManager : Approver
{
    public override void ProcessRequest(PurchaseOrder purchase)
    {
        if (purchase.Price < 10000)
        {
            Console.WriteLine("{0} approved purchase request #{1}",
                this.GetType().Name, purchase.RequestNumber);
        }
        else
        {
            Console.WriteLine(
                "Purchase request #{0} requires an executive meeting!",
                purchase.RequestNumber);
        }
    }
}

客戶端呼叫:

static void Main(string[] args)
{
    //Create the chain links
    Approver jennifer = new HeadChef();
    Approver mitchell = new PurchasingManager();
    Approver olivia = new GeneralManager();

    //Create the chain
    jennifer.SetSupervisor(mitchell);
    mitchell.SetSupervisor(olivia);

    // Generate and process purchase requests
    PurchaseOrder p = new PurchaseOrder(1, 20, 69, "Spices");
    jennifer.ProcessRequest(p);

    p = new PurchaseOrder(2, 300, 1389, "Fresh Veggies");
    jennifer.ProcessRequest(p);

    p = new PurchaseOrder(3, 500, 4823.99, "Beef");
    jennifer.ProcessRequest(p);

    p = new PurchaseOrder(4, 4, 12099, "Ovens");
    jennifer.ProcessRequest(p);

    // Wait for user
    Console.ReadKey();
}

總結

責任鏈模式允許鏈中的多個物件在處理請求物件時進行傳遞。請求流經鏈,直到鏈中的一個環節處理它。

原始碼

https://github.com/exceptionnotfound/DesignPatterns/tree/master/ChainOfResponsibility

原文

https://www.exceptionnotfound.net/chain-of-responsibility-the-daily-design-pattern/