职责链模式

职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

下面举例说明,实现员工提交请求,主管层层审批:

首先定义请求类

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对象负责处理它,而客户并不知道实际是由哪个对象处理了请求。接受者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可以简化对象的相互连接,他们仅需保持一个指向其后继的引用,而不需要保持它所有的候选者的引用,从而降低了耦合度也可以随时的增加或修改链的结构,增强了指派职责的灵活性。

不过要小心,一个请求极有可能到了链的末端都得不到处理,或者因为没有正确的配置而得不到处理,因此职责链的设置需要事先考虑全面。

 

  

  

原文地址:https://www.cnblogs.com/angela217/p/5477037.html