职责链模式
职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
下面举例说明,实现员工提交请求,主管层层审批:
首先定义请求类
public class Request
{
public string RequestType { get; set; }
public int RequestNum { get; set; }
public string Requestor { get; set; }
public Request(string RequestType, int RequestNum, string Requestor)
{
this.RequestType = RequestType;
this.RequestNum = RequestNum;
this.Requestor = Requestor;
}
}
下面定义职责链中的审批人:
/// <summary>
/// 处理请求的借口,可以设置下一级处理人
/// </summary>
abstract public class Handler
{
protected string Name { get; set; }
protected Handler nextHandler;
public Handler(string name)
{
Name = name;
}
public void SetNextHandler(Handler superior)
{
nextHandler = superior;
}
abstract public void HandleRequest(Request requests);
}
/// <summary>
/// 具体的处理者,处理它所负责的请求,将无权处理的请求转发给后继者
/// </summary>
public class Manager : Handler
{
public Manager(string name) : base(name) { }
public override void HandleRequest(Request request)
{
if (request.RequestType == "Leave" && request.RequestNum < 5)
{
Console.WriteLine("{0}的{1}申请,天数{2},批准人{3}。", request.Requestor, request.RequestType, request.RequestNum, Name);
}
else if (nextHandler != null)
{
nextHandler.HandleRequest(request);
}
else
{
Console.WriteLine("{0}的{1}申请,天数{2},无人审批。", request.Requestor, request.RequestType, request.RequestNum);
}
}
}
public class Director : Handler
{
public Director(string name) : base(name) { }
public override void HandleRequest(Request request)
{
if (request.RequestType == "Leave" && request.RequestNum < 10)
{
Console.WriteLine("{0}的{1}申请,天数{2},批准人{3}。", request.Requestor, request.RequestType, request.RequestNum, Name);
}
else if (request.RequestType == "Salary" && request.RequestNum < 1000)
{
Console.WriteLine("{0}的{1}申请,金额{2},批准人{3}。", request.Requestor, request.RequestType, request.RequestNum, Name);
}
else if (nextHandler != null)
{
nextHandler.HandleRequest(request);
}
else
{
Console.WriteLine("{0}的{1}申请,天数{2},无人审批。", request.Requestor, request.RequestType, request.RequestNum);
}
}
}
public class VP : Handler
{
public VP(string name) : base(name) { }
public override void HandleRequest(Request request)
{
if (request.RequestType == "Leave")
{
Console.WriteLine("{0}的{1}申请,天数{2},批准人{3}。", request.Requestor, request.RequestType, request.RequestNum, Name);
}
else if (request.RequestType == "Salary")
{
Console.WriteLine("{0}的{1}申请,金额{2},批准人{3}。", request.Requestor, request.RequestType, request.RequestNum, Name);
}
else if (nextHandler != null)
{
nextHandler.HandleRequest(request);
}
else
{
Console.WriteLine("{0}的{1}申请,天数{2},无人审批。", request.Requestor, request.RequestType, request.RequestNum);
}
}
}
客户端设置请求和审批的职责链:
Manager manager = new Manager("小经理");
Director director = new Director("总监");
VP vp = new VP("副总裁");
//经理的下级审批人士总监
manager.SetNextHandler(director);
//总监的下级审批人士副总裁
director.SetNextHandler(vp);
Request leaveRequest1 = new Request("Leave",3,"毛毛");
manager.HandleRequest(leaveRequest1);
Request leaveRequest2 = new Request("Leave", 8, "朵朵");
manager.HandleRequest(leaveRequest2);
Request leaveRequest3 = new Request("Leave", 12, "绒绒");
manager.HandleRequest(leaveRequest3);
Request salaryRequest1 = new Request("Salary", 800, "毛毛");
manager.HandleRequest(salaryRequest1);
Request salaryRequest2 = new Request("Salary", 1500, "嘟嘟");
manager.HandleRequest(salaryRequest2);
执行结果为:
毛毛的Leave申请,天数3,批准人小经理。
朵朵的Leave申请,天数8,批准人总监。
绒绒的Leave申请,天数12,批准人副总裁。
毛毛的Salary申请,金额800,批准人总监。
嘟嘟的Salary申请,金额1500,批准人副总裁。
可以看出,当客户提交一个请求时,请求是沿着职责链传递,直到有一个ConcreteHandler对象负责处理它,而客户并不知道实际是由哪个对象处理了请求。接受者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可以简化对象的相互连接,他们仅需保持一个指向其后继的引用,而不需要保持它所有的候选者的引用,从而降低了耦合度也可以随时的增加或修改链的结构,增强了指派职责的灵活性。
不过要小心,一个请求极有可能到了链的末端都得不到处理,或者因为没有正确的配置而得不到处理,因此职责链的设置需要事先考虑全面。

浙公网安备 33010602011771号