责任链模式(Chain of Responsibility Pattern)
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。请求沿着对象链传递,直到有一个对象处理它为止。
关键点
- 抽象处理者(Handler):定义了处理请求的接口,并且持有下一个处理者的引用。
- 具体处理者(ConcreteHandler):实现了处理请求的方法,如果自己能够处理则处理,否则将请求转发给下一个处理者。
- 客户端(Client):创建并且将请求发送给链中的第一个处理者,从而开始请求的处理。
示例
假设我们需要构建一个审批系统,有多个处理者来处理不同金额级别的审批请求。我们可以使用责任链模式来实现这个审批流程。
1. 定义抽象处理者接口
csharp
// 抽象处理者
public abstract class Approver
{
protected Approver successor; // 后继者
public void SetSuccessor(Approver successor)
{
this.successor = successor;
}
public abstract void ProcessRequest(Purchase purchase);
}
2. 创建具体处理者
csharp
// 具体处理者 - 主管
public class Supervisor : Approver
{
public override void ProcessRequest(Purchase purchase)
{
if (purchase.Amount <= 1000)
{
Console.WriteLine($"{nameof(Supervisor)} approved request #{purchase.Number}");
}
else if (successor != null)
{
successor.ProcessRequest(purchase);
}
}
}
// 具体处理者 - 经理
public class Manager : Approver
{
public override void ProcessRequest(Purchase purchase)
{
if (purchase.Amount <= 5000)
{
Console.WriteLine($"{nameof(Manager)} approved request #{purchase.Number}");
}
else if (successor != null)
{
successor.ProcessRequest(purchase);
}
}
}
// 具体处理者 - 总经理
public class Director : Approver
{
public override void ProcessRequest(Purchase purchase)
{
if (purchase.Amount <= 10000)
{
Console.WriteLine($"{nameof(Director)} approved request #{purchase.Number}");
}
else
{
Console.WriteLine($"Request #{purchase.Number} requires a board meeting!");
}
}
}
3. 创建请求类
csharp
// 请求类
public class Purchase
{
public int Number { get; set; }
public double Amount { get; set; }
public string Purpose { get; set; }
public Purchase(int number, double amount, string purpose)
{
Number = number;
Amount = amount;
Purpose = purpose;
}
}
4. 客户端代码
csharp
class Program
{
static void Main(string[] args)
{
// 创建处理者
Approver supervisor = new Supervisor();
Approver manager = new Manager();
Approver director = new Director();
// 设置责任链
supervisor.SetSuccessor(manager);
manager.SetSuccessor(director);
// 创建请求
Purchase purchase1 = new Purchase(1, 800, "Office supplies");
Purchase purchase2 = new Purchase(2, 3500, "Project materials");
Purchase purchase3 = new Purchase(3, 15000, "New office furniture");
// 处理请求
supervisor.ProcessRequest(purchase1);
supervisor.ProcessRequest(purchase2);
supervisor.ProcessRequest(purchase3);
}
}
解释
- 抽象处理者(Approver):定义了处理请求的接口
ProcessRequest
,并且持有下一个处理者的引用successor
。 - 具体处理者(Supervisor、Manager、Director):实现了处理请求的具体逻辑,如果自己能够处理则处理,否则转发给下一个处理者。
- 客户端代码:创建具体处理者并设置责任链的顺序,然后创建请求并通过第一个处理者处理请求。
优点
- 降低耦合度:请求的发送者和接收者之间解耦,增强了系统的灵活性。
- 增强对象的复用性:可以灵活地组合和复用处理者对象。
- 增加新的请求处理类容易:可以通过增加新的具体处理者来扩展责任链,无需修改现有代码。
缺点
- 请求不一定被处理:如果责任链没有正确配置,可能会导致请求无法被处理。
- 性能问题:由于责任链的特性,请求可能需要沿着链路传递,如果责任链过长或者处理逻辑复杂,可能会影响性能。
适用场景
- 多个对象可以处理同一请求:例如工作流程中的审批流程。
- 动态指定处理链:可以动态地指定处理链的顺序和组成。
- 需要避免请求发送者和接收者之间的耦合关系:例如消息处理系统、事件处理等。
示例的现实应用
责任链模式在实际应用中有广泛的应用,特别是在处理复杂请求和流程中:
- 审批流程:不同级别的审批者依次处理请求。
- 异常处理:在软件系统中,可以通过责任链模式来处理异常,使得每个处理者负责处理一种类型的异常。
- 日志记录:责任链模式可以用于日志记录器链,每个日志记录器处理不同级别的日志消息。