码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式(19)---职责链模式

时间:2014-12-15 17:13:56      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   color   os   使用   sp   

一、定义

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

解释:简单来说应该是对于一个请求,不同的人根据自己职责范围对它进行处理,同时也因为它一般是从底层向上层传递的请求的,所以将处理该请求的不同的对象比喻成一个链,从相对“低”的地方传递到相对“高”的地方,从而完成请求操作。

 

二、UML类图及基本代码

bubuko.com,布布扣

基本代码:

abstract class Handler
    {
        protected Handler successor;

        public void SetSuccessor(Handler successor)
        {
            this.successor = successor;
        }

        public abstract void HandleRequest(int request);
    }

    class ConcreteHandler1 : Handler
    {
        public override void HandleRequest(int request)
        {
            if (request >= 0 && request < 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);
            }
        }
    }

 

客户端调用及其结果:

bubuko.com,布布扣
Handler h1 = new ConcreteHandler1();
            Handler h2 = new ConcreteHandler2();
            Handler h3 = new ConcreteHandler3();
            h1.SetSuccessor(h2);
            h2.SetSuccessor(h3);

            int[] requests = { 6, 5, 14, 23, 18, 9, 17, 6, 26 };
            foreach (int request in requests)
            {
                h1.HandleRequest(request);
            }
View Code

bubuko.com,布布扣

 

三、具体实例

列举一个能更加说明职责链的实例。john在单位,向领导请假,小于等于2天经理有权利批准,小于等于5天总监有权利批准,其他的则要交到总经理那里批准。具体代码如下:

bubuko.com,布布扣
class Request
    {
        public string RequestType{get;set;}
        public string RequestContent{get;set;}
        public int Number{get;set;}
    }

    abstract class Manager
    {
        protected string name;
        protected Manager superior;

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

        public void SetSuperior(Manager superior)
        {
            this.superior = superior;
        }

        public abstract void RequestApplications(Request request);
    }

    class CommonManager : Manager
    {
        public CommonManager(string name)
            : base(name)
        { }

        public override void RequestApplications(Request request)
        {
            if (request.RequestType == "leave" && request.Number <= 2)
            {
                Console.WriteLine("{0}:{1} number is {2} ok", name, request.RequestContent, request.Number);
            }
            else
            {
                if (superior != null)
                {
                    superior.RequestApplications(request);
                }
            }
        }
    }

    class Majordome : Manager
    {
        public Majordome(string name)
            : base(name)
        { }

        public override void RequestApplications(Request request)
        {
            if (request.RequestType == "leave" && request.Number <= 5)
            {
                Console.WriteLine("{0}:{1} number is {2} ok", 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 == "leave")
            {
                Console.WriteLine("{0}:{1} number is {2} ok", name, request.RequestContent, request.Number);
            }
            else if (request.RequestType == "add money" && request.Number <= 500)
            {
                Console.WriteLine("{0}:{1} number is {2} ok", name, request.RequestContent, request.Number);
            }
            else if (request.RequestType == "add money" && request.Number > 500)
            {
                Console.WriteLine("{0}:{1} number is {2} not ok", name, request.RequestContent, request.Number);
            }
        }
    }
View Code

 

客户端调用及结果:

bubuko.com,布布扣
CommonManager jinli = new CommonManager("经理");
            Majordome zongjian = new Majordome("总监");
            GeneralManager zhongjingli = new GeneralManager("总经理");
            jinli.SetSuperior(zongjian);
            zongjian.SetSuperior(zhongjingli);

            Request request = new Request();
            request.RequestType = "leave";
            request.RequestContent = "john ask for days";
            request.Number = 2;
            jinli.RequestApplications(request);

            Request request2 = new Request();
            request2.RequestType = "leave";
            request2.RequestContent = "john ask for days";
            request2.Number = 5;
            jinli.RequestApplications(request2);
View Code

bubuko.com,布布扣

 

四、优缺点及适用场景

优点:

1)降低了请求发送者和处理者之间的耦合。

2)把多个条件判定分散到各个处理类中,使得代码更加清晰,责任更加明确。

缺点:

1)在找到正确的处理对象之前,所有的条件判定都要执行一遍,当职责链过长时,可能会引起性能问题。

2)可能导致某个请求不被处理。

 

适用场景:

1)一个系统的请求需要多个对象进行审批才能完成的情况。

2)代码中有多个if-else时,也可以考虑使用职责链模式对代码进行重构。

 

设计模式(19)---职责链模式

标签:style   blog   http   io   ar   color   os   使用   sp   

原文地址:http://www.cnblogs.com/ysyn/p/4164969.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!