zoukankan      html  css  js  c++  java
  • 设计模式(19)---职责链模式

    一、定义

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

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

    二、UML类图及基本代码

    基本代码:

    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);
                }
            }
        }

    客户端调用及其结果:

    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

    三、具体实例

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

    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

    客户端调用及结果:

    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

    四、优缺点及适用场景

    优点:

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

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

    缺点:

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

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

    适用场景:

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

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

  • 相关阅读:
    error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 E:OCX
    JQUERY解析XML IE8的兼容问题
    IE11下,IIS7.5不自动生成__doPostBack事件
    IE11无法支持Forms认证,,,也就是无法保存COOKIE
    IIS7.5真变态,服务器时间格式导致不生成WebResource.axd
    django ajax MTV与MVC 多对多创建方式
    django F与Q查询 事务 only与defer
    模型层
    模板层(模板语法)
    django 路由层 伪静态网页 虚拟环境 视图层
  • 原文地址:https://www.cnblogs.com/ysyn/p/4164969.html
Copyright © 2011-2022 走看看