模式介绍
责任链设计模式试图通过给不止一个对象处理特定请求的机会,来避免将请求耦合到特定接收器。
本质上,我们沿着该对象的潜在处理程序的“链”传递对象,直到其中一个处理程序处理请求。
示例
我们还是以餐馆建模。
想一下,当厨房需要采购新设备,厨师长需要像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/