首页 > 技术文章 > 加薪非要老总批? 职责链模式

huangxuQaQ 2019-08-08 11:03 原文

24.1 老板,我要加薪!

24.2 加薪代码初步

namespace 职责链模式
{
    enum ManagerLevel { 经理, 总监, 总经理 }

    class Program
    {
        static void Main(string[] args)
        {

            Manager jinli = new Manager("金利");
            Manager zongjian = new Manager("宗剑");
            Manager zhongjingli = new Manager("钟精励");

            Request request = new Request();
            request.RequestType = "加薪";
            request.RequestContent = "小菜请求加薪";
            request.Number = 1000;

            jinli.GetResult(ManagerLevel.经理, request);
            zongjian.GetResult(ManagerLevel.总监, request);
            zhongjingli.GetResult(ManagerLevel.总经理, request);

            Request request2 = new Request();
            request2.RequestType = "请假";
            request2.RequestContent = "小菜请假";
            request2.Number = 3;

            jinli.GetResult(ManagerLevel.经理, request2);
            zongjian.GetResult(ManagerLevel.总监, request2);
            zhongjingli.GetResult(ManagerLevel.总经理, request2);

            Console.Read();
        }
    }


    //管理者,
    class Manager
    {

        protected string name;

        public Manager(string name)
        {
            this.name = name;
        }

        //得到结果,
        public void GetResult(ManagerLevel managerLevel, Request request)
        {
            if (managerLevel == ManagerLevel.经理)
            {
                if (request.RequestType == "请假" && request.Number <= 2)
                {
                    Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
                }
                else
                {
                    Console.WriteLine("{0}:{1} 数量{2} 我无权处理", name, request.RequestContent, request.Number);
                }

            }
            else if (managerLevel == ManagerLevel.总监)
            {
                if (request.RequestType == "请假" && request.Number <= 5)
                {
                    Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
                }
                else
                {
                    Console.WriteLine("{0}:{1} 数量{2} 我无权处理", name, request.RequestContent, request.Number);
                }
            }
            else if (managerLevel == ManagerLevel.总经理)
            {
                if (request.RequestType == "请假")
                {
                    Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
                }
                else if (request.RequestType == "加薪" && request.Number <= 500)
                {
                    Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
                }
                else if (request.RequestType == "加薪" && request.Number > 500)
                {
                    Console.WriteLine("{0}:{1} 数量{2} 再说吧", name, request.RequestContent, request.Number);
                }
            }
        }
    }

    //申请,
    class Request
    {
        //申请类别,
        private string requestType;

        public string RequestType
        {
            get { return requestType; }
            set { requestType = value; }
        }

        //申请内容,
        private string requestContent;

        public string RequestContent
        {
            get { return requestContent; }
            set { requestContent = value; }
        }

        //数量,
        private int number;

        public int Number
        {
            get { return number; }
            set { number = value; }
        }
    }

}
View Code

24.3 职责链模式

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

namespace 职责链模式
{
    class Program
    {
        static void Main(string[] args)
        {
            Handler h1 = new ConcreteHandler1();
            Handler h2 = new ConcreteHandler2();
            Handler h3 = new ConcreteHandler3();
            h1.SetSuccessor(h2);                              //设置职责链上家与下家,
            h2.SetSuccessor(h3);

            int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };

            foreach (int request in requests)                 //循环给最小处理者提交请求,不同的数值由不同权限处理者处理,
            {
                h1.HandleRequest(request);
            }

            Console.Read();
        }
    }

    //定义一个处理请示的接口,
    abstract class Handler
    {
        protected Handler successor;

        public void SetSuccessor(Handler successor)           //设置继任者,
        {
            this.successor = successor;
        }

        public abstract void HandleRequest(int request);      //处理请求的抽象方法,
    }

    //ConcreteHandler类,具体处理者类,处理它所负责的请求,可访问它的后继者,
    //如果可处理该请求,就处理之,否则就将该请求转发给它的后继者,
    class ConcreteHandler1 : Handler
    {
        public override void HandleRequest(int request)
        {
            if (request >= 0 && request < 10)               //当请求数在0-10之间有权处理,否则转到下一位,
            {
                Console.WriteLine("{0}  处理请求  {1}",
                  this.GetType().Name, request);
            }
            else if (successor != null)
            {
                successor.HandleRequest(request);          //转到下一位,
            }
        }
    }

    class ConcreteHandler2 : Handler
    {
        public override void HandleRequest(int request)
        {
            if (request >= 10 && request < 20)
            {
                Console.WriteLine("{0}  处理请求  {1}",
                  this.GetType().Name, request);
            }
            else if (successor != null)
            {
                successor.HandleRequest(request);
            }
        }
    }

    class ConcreteHandler3 : Handler
    {
        public override void HandleRequest(int request)
        {
            if (request >= 20 && request < 30)
            {
                Console.WriteLine("{0}  处理请求  {1}",
                  this.GetType().Name, request);
            }
            else if (successor != null)
            {
                successor.HandleRequest(request);
            }
        }
    }

}
View Code

24.4 职责链的好处

这当中最关键的是当用户提交一个请求时,请求是沿链传递直至有一个ConcreteHandler对象负责处理它,

这样做的好处是不是说请求者不用管哪个对象来处理,反正该请求会被处理就对了?yes,这就使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构,结果是职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用而不需保持它所有的候选接收者的引用,这也就大大降低了耦合度了,

也可以随时的增加或修改处理一个请求的结构,增强了给对象指派职责的灵活性,

不过也要当心,一个请求极有可能到了链的末端都得不到处理,或者因为没有正确的配置而得不到处理,

24.5 加薪代码重构

把原来的一个管理者类改成了一个抽象类和三个具体类,此时类之间的灵活性就大大增加了,如果我们需要扩展新的管理者类别,只需要增加子类就可以,但要注意客户端的编写,

namespace 职责链模式
{
    class Program
    {
        static void Main(string[] args)
        {

            CommonManager jinli = new CommonManager("金利");
            Majordomo zongjian = new Majordomo("宗剑");
            GeneralManager zhongjingli = new GeneralManager("钟精励");

            jinli.SetSuperior(zongjian);                                //设置上级,完全可以根据实际需求来更改设置,
            zongjian.SetSuperior(zhongjingli);

            Request request = new Request();
            request.RequestType = "请假";
            request.RequestContent = "小菜请假";
            request.Number = 1;
            jinli.RequestApplications(request);                         //客户端的申请都是由经理发起,但实际谁来决策由具体管理类来处理,客户端不知道,

            Request request2 = new Request();
            request2.RequestType = "请假";
            request2.RequestContent = "小菜请假";
            request2.Number = 4;
            jinli.RequestApplications(request2);

            Request request3 = new Request();
            request3.RequestType = "加薪";
            request3.RequestContent = "小菜请求加薪";
            request3.Number = 500;
            jinli.RequestApplications(request3);

            Request request4 = new Request();
            request4.RequestType = "加薪";
            request4.RequestContent = "小菜请求加薪";
            request4.Number = 1000;
            jinli.RequestApplications(request4);

            Console.Read();
        }
    }

    //管理者,
    abstract class Manager
    {
        protected string name;

        //管理者的上级,
        protected Manager superior;

        public Manager(string name)
        {
            this.name = name;
        }

        //设置管理者的上级,
        public void SetSuperior(Manager superior)
        {
            this.superior = superior;
        }

        //申请请求,
        abstract public void RequestApplications(Request request);
    }

    //经理,
    class CommonManager : Manager
    {
        public CommonManager(string name)
            : base(name)
        { }

        public override void RequestApplications(Request request)
        {

            if (request.RequestType == "请假" && request.Number <= 2)
            {
                Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
            }
            else
            {
                if (superior != null)
                    superior.RequestApplications(request);
            }
        }
    }

    //总监,
    class Majordomo : Manager
    {
        public Majordomo(string name)
            : base(name)
        { }

        public override void RequestApplications(Request request)
        {

            if (request.RequestType == "请假" && request.Number <= 5)
            {
                Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
            }
            else
            {
                if (superior != null)
                    superior.RequestApplications(request);
            }
        }
    }

    //总经理,
    class GeneralManager : Manager
    {
        public GeneralManager(string name)
            : base(name)
        { }

        public override void RequestApplications(Request request)
        {

            if (request.RequestType == "请假")
            {
                Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
            }
            else if (request.RequestType == "加薪" && request.Number <= 500)
            {
                Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
            }
            else if (request.RequestType == "加薪" && request.Number > 500)
            {
                Console.WriteLine("{0}:{1} 数量{2} 再说吧", name, request.RequestContent, request.Number);
            }
        }
    }

    //申请,
    class Request
    {
        //申请类别,
        private string requestType;

        public string RequestType
        {
            get { return requestType; }
            set { requestType = value; }
        }

        //申请内容,
        private string requestContent;

        public string RequestContent
        {
            get { return requestContent; }
            set { requestContent = value; }
        }

        //数量,
        private int number;

        public int Number
        {
            get { return number; }
            set { number = value; }
        }
    }

}
View Code

24.6 加薪成功

推荐阅读