設計模式(13)責任鏈模式
阿新 • • 發佈:2018-11-01
模式介紹
責任鏈設計模式試圖通過給不止一個物件處理特定請求的機會,來避免將請求耦合到特定接收器。
本質上,我們沿著該物件的潛在處理程式的“鏈”傳遞物件,直到其中一個處理程式處理請求。
示例
我們還是以餐館建模。
想一下,當廚房需要採購新裝置,廚師長需要像Boss請示。
我們的店裡的採購流程是這樣的:
- 1000元以內,廚師長自己就可以做決定
- 1000-2500元,必須報採購經理審批
- 2500-10000元,必須報總經理審批
- 超過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/