模式简介
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一个链,并沿着链传递该请求,直到有一个对象处理它为止。
职责链模式是一种行为型模式,它包括命令对象以及一系列处理对象。每个处理对象决定它能够处理哪些命令对象,将不能处理的命令对象传递至职责链中的下一个处理对象。
想象一下公司的OA系统,提交请假单时系统会根据你的请假天数将申请单"交给"不同的人去审批,例如请假1-2天,只需要Team Leader审批,3-5天需要Manager审批,大于5天需要Director审批,这就形成了一个职责链。假如你要请假1个月,系统首先把请求传递给Leader对象,Leader对象发现自己无法处理这个请求,将请求传递给Manager对象,Manager也无法处理,再传递给Director。
结构说明
角色说明
- Handler
定义一个处理请求的接口。
- ConcreteHandler
实际负责处理请求的类。如果符合条件,处理该请求,否则转发给后续的ConcreteHandler。
结构代码
声明抽象类Handler,定义一个处理请求的接口。
public abstract class Handler
{
protected Handler _successor;
public void SetSuccessor(Handler successor)
{
this._successor = successor;
}
public abstract void Handle(int request);
}
具体实现类,负责处理请求。ConcreteHanlder1处理reqeust小于等于10的请求,其他由ConcreteHandler2进行处理。
class ConcreteHandler1 : Handler
{
public override void Handle(int request)
{
if (request <= 10)
{
Console.WriteLine($"{this.GetType().Name} handled request {request}");
}
else if (_successor != null)
{
_successor.Handle(request);
}
}
}
class ConcreteHandler2 : Handler
{
public override void Handle(int request)
{
if (request > 10)
{
Console.WriteLine($"{this.GetType().Name} handled request {request}");
}
else if (_successor != null)
{
_successor.Handle(request);
}
}
}
客户端调用,设置职责链h1 -> h2,依次对requests数组中的元素进行处理。
class Program
{
static void Main(string[] args)
{
ConcreteHandler1 h1 = new ConcreteHandler1();
ConcreteHandler2 h2 = new ConcreteHandler2();
h1.SetSuccessor(h2);
int[] requests = { 1, 4, 5, 11, 24 };
foreach (var request in requests)
{
h1.Handle(request);
}
Console.ReadLine();
}
}
输出结果:
工作原理
当用户提交一个请求,请求将沿着职责链依次传递知道有一个ConcreteHandler对象负责处理它。
示例分析
回到本篇开头请假申请的示例,本节我们将通过职责链模式来实现它,首先创建请求类LeaveReqeust,包含申请人以及申请天数,
class LeaveRequest
{
public string Applicant { get; set; }
public int Days { get; set; }
}
声明抽象类Approver,定义一个处理请求的抽象方法Approve。
abstract class Approver
{
protected Approver _successor;
public void SetSuccessor(Approver successor)
{
_successor = successor;
}
public abstract void Approve(LeaveRequest request);
}
声明Leader、Manager、Director三个实际处理请求的类。
class Leader : Approver
{
public override void Approve(LeaveRequest request)
{
if (request.Days <= 2)
{
Console.WriteLine($"{this.GetType().Name} approved request {request.Applicant},{request.Days}");
}
else if (_successor != null)
{
_successor.Approve(request);
}
}
}
class Manager : Approver
{
public override void Approve(LeaveRequest request)
{
if (request.Days <= 5)
{
Console.WriteLine($"{this.GetType().Name} approved request {request.Applicant},{request.Days}");
}
else if (_successor != null)
{
_successor.Approve(request);
}
}
}
class Director : Approver
{
public override void Approve(LeaveRequest request)
{
Console.WriteLine($"{this.GetType().Name} approved request {request.Applicant},{request.Days}");
}
}
客户端调用,创建职责链leader->manager->director,接着创建3个请求传递给职责链,依次处理。
class Program
{
static void Main(string[] args)
{
Leader leader = new Leader();
Manager manager = new Manager();
Director director = new Director();
leader.SetSuccessor(manager);
manager.SetSuccessor(director);
LeaveRequest jack = new LeaveRequest
{
Applicant = "Jack",
Days = 2
};
LeaveRequest tom = new LeaveRequest
{
Applicant = "Tom",
Days = 30
};
LeaveRequest mike = new LeaveRequest
{
Applicant = "Mike",
Days = 4
};
leader.Approve(jack);
leader.Approve(tom);
leader.Approve(mike);
Console.ReadLine();
}
}
输出结果:
适用场景
-
由多个对象处理一个请求,在运行时确定具体使哪个对象进行处理
-
职责链可以动态指定