职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
下面举例说明,实现员工提交请求,主管层层审批:
首先定义请求类
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对象负责处理它,而客户并不知道实际是由哪个对象处理了请求。接受者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可以简化对象的相互连接,他们仅需保持一个指向其后继的引用,而不需要保持它所有的候选者的引用,从而降低了耦合度也可以随时的增加或修改链的结构,增强了指派职责的灵活性。
不过要小心,一个请求极有可能到了链的末端都得不到处理,或者因为没有正确的配置而得不到处理,因此职责链的设置需要事先考虑全面。