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

责任链模式(Chain of Responsibility)

时间:2018-02-02 20:22:55      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:开头   ide   type   博客   handler   实现   ima   rtm   com   

模式定义

责任链模式(Chain of Responsibility): 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条对象连成一条链,并沿着这条链传递请求。

UML类图

技术分享图片

  • 抽象处理者(Handler) :定义一个处理请求的接口。聚合自己类型,用来设置请求的处理的下家对象。
  • 具体处理者(Concrete Handler): 实现请求方法,处理掉或者传递给下家对象。
  • 客户端(Client):设置处理链,并调用。

    代码结构

    class ChainClient
    {
         public void Run()
        {
            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.ReadKey();
        }
    }
    
    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} handled request {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} handled request {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} handled request {1}",this.GetType().Name, request);
            }
            else if (successor != null)
            {
                successor.HandleRequest(request);
            }
        }
    }

    情景案例

    这里以大学中请假为例:少于2天班长处理,少5天指导员处理,少于30天系主任处理,大于30天不允许。

    class RealWorldChainClient
    {
        public void Run()
        {
            Approver h1 = new Monitor();
            Approver h2 = new Instructor();
            Approver h3 = new DepartmentHead();
            h1.SetSuccessor(h2);
            h2.SetSuccessor(h3);
    
            int[] requests = { 2, 5, 14, 35 };
    
            foreach (int request in requests)
            {
                h1.HandleRequest(request);
            }
            Console.ReadKey();
        }
    }
    
    abstract class Approver
    {
        protected Approver successor;
    
        public void SetSuccessor(Approver successor)
        {
            this.successor = successor;
        }
    
        public abstract void HandleRequest(int days);
    }
    
    /// <summary>
    /// 班长
    /// </summary>
    class Monitor : Approver
    {
        public override void HandleRequest(int days)
        {
            if (days >= 0 && days <= 2)
            {
                Console.WriteLine("我是班长,批准请假{0}天",days);
            }
            else if (successor != null)
            {
                successor.HandleRequest(days);
            }
        }
    }
    
    /// <summary>
    /// 指导员
    /// </summary>
    class Instructor : Approver
    {
        public override void HandleRequest(int days)
        {
            if (days >= 0 && days < 10)
            {
                Console.WriteLine("我是指导员,批准请假{0}天", days);
            }
            else if (successor != null)
            {
                successor.HandleRequest(days);
            }
        }
    }
    
    /// <summary>
    /// 系主任
    /// </summary>
    class DepartmentHead : Approver
    {
        public override void HandleRequest(int days)
        {
            if (days >= 0 && days < 30)
            {
                Console.WriteLine("我是指导员,批准请假{0}天", days);
            }
            else
            {
                Console.WriteLine("请假天数太多了,退学吧!");
            }
        }
    }

    自问自答

    小a:你的博客好冷清呀!!!我感觉你上面将的例子还不如用if()....else....简单明了,整那么多类倒是增加了复杂性,感觉真个模式没必要?

LoveTomato: 啊!!!确实博客比较冷清,万事开头难吗?开头难也要开头的吗。
回答正题 确实业务比较简单,顺序编程简单快捷。但是项目中往往有比较复杂的,如好多网站有需要用户填入的表单,后台验证数据的有效性。假设验证的指标有

  1. 必填性验证
  2. 数据类型验证(时间类型的值是否有效等)
  3. 业务验证(需要查询数据库)

这样每个验证都需要大段的代码,在if...else中维护的心情你懂的,而且每次添加项新的验证都需要修改if...else

责任链模式(Chain of Responsibility)

标签:开头   ide   type   博客   handler   实现   ima   rtm   com   

原文地址:https://www.cnblogs.com/LoveTomato/p/8406461.html

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