zoukankan      html  css  js  c++  java
  • Head First设计模式之责任链模式

    一、定义

      避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

      主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。

      何时使用:在处理消息的时候以过滤很多道。

      如何解决:拦截的类都实现统一接口。

    二、结构

     从责任链模式的定义可以发现,责任链模式涉及的对象只有处理者角色,但由于有多个处理者,它们具有共同的处理请求的方法,所以这里抽象出一个抽象处理者角色进行代码复用。这样分析下来,责任链模式的结构图也就不言而喻了,具体结构图如下所示。

      主要涉及两个角色:

    • 抽象处理者角色(Handler):定义出一个处理请求的接口。这个接口通常由接口或抽象类来实现。
    • 具体处理者角色(ConcreteHandler):具体处理者接受到请求后,可以选择将该请求处理掉,或者将请求传给下一个处理者。因此,每个具体处理者需要保存下一个处理者的引用,以便把请求传递下去。

    三、适用场景

    1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。

    2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。

    3、可动态指定一组对象处理请求。

    四、优缺点

    优点: 

    1、降低耦合度。它将请求的发送者和接收者解耦。

    2、简化了对象。使得对象不需要知道链的结构。

    3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。

    4、增加新的请求处理类很方便。

     

    缺点: 

    1、不能保证请求一定被接收。

    2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。

    3、可能不容易观察运行时的特征,有碍于除错。

    五、实现

       以公司采购东西为例来实现责任链模式。公司规定,采购架构总价在1万之内,经理级别的人批准即可,总价大于1万小于2万5的则还需要副总进行批准,总价大于2万5小于10万的需要还需要总经理批准,而大于总价大于10万的则需要组织一个会议进行讨论。  

    // 采购请求
        public class PurchaseRequest
        {
            // 金额
            public double Amount { get; set; }
            // 产品名字
            public string ProductName { get; set; }
            public PurchaseRequest(double amount, string productName)
            {
                Amount = amount;
                ProductName = productName;
            }
        }
    
        // 审批人,Handler
        public abstract class Approver
        {
            public Approver NextApprover { get; set; }
            public string Name { get; set; }
            public Approver(string name)
            {
                this.Name = name;
            }
            public abstract void ProcessRequest(PurchaseRequest request);
        }
    
        // ConcreteHandler
        public class Manager : Approver
        {
            public Manager(string name)
                : base(name)
            { }
    
            public override void ProcessRequest(PurchaseRequest request)
            {
                if (request.Amount < 10000.0)
                {
                    Console.WriteLine("{0} 批准购买 {1}", Name, request.ProductName);
                }
                else if (NextApprover != null)
                {
                    NextApprover.ProcessRequest(request);
                }
            }
        }
    
        // ConcreteHandler,副总
        public class VicePresident : Approver
        {
            public VicePresident(string name)
                : base(name)
            {
            }
            public override void ProcessRequest(PurchaseRequest request)
            {
                if (request.Amount < 25000.0)
                {
                    Console.WriteLine("{0} 批准购买 {1}", Name, request.ProductName);
                }
                else if (NextApprover != null)
                {
                    NextApprover.ProcessRequest(request);
                }
            }
        }
    
        // ConcreteHandler,总经理
        public class President : Approver
        {
            public President(string name)
                : base(name)
            { }
            public override void ProcessRequest(PurchaseRequest request)
            {
                if (request.Amount < 100000.0)
                {
                    Console.WriteLine("{0} 批准购买 {1}",  Name, request.ProductName);
                }
                else
                {
                    Console.WriteLine("Request需要组织一个会议讨论");
                }
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                PurchaseRequest requestTelphone = new PurchaseRequest(4000.0, "手机");
                PurchaseRequest requestSoftware = new PurchaseRequest(10000.0, "空调");
                PurchaseRequest requestComputers = new PurchaseRequest(40000.0, "笔记本电脑");
    
                Approver manager = new Manager("经理");
                Approver Vp = new VicePresident("副总");
                Approver Pre = new President("总经理");
    
                // 设置责任链
                manager.NextApprover = Vp;
                Vp.NextApprover = Pre;
    
                // 处理请求
                manager.ProcessRequest(requestTelphone);
                manager.ProcessRequest(requestSoftware);
                manager.ProcessRequest(requestComputers);
                Console.ReadLine();
            }
        }

    结果

    经理 批准购买 手机
    副总 批准购买 空调
    总经理 批准购买 笔记本电脑

    参考:

    http://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html

    http://www.cnblogs.com/zhili/p/ChainOfResponsibity.html

    欢迎阅读本系列文章:Head First设计模式之目录 

  • 相关阅读:
    02_5if switch分支与循环语句
    02_4运算符
    02_3程序格式
    Shell脚本调用ftp上传文件
    02_2数据类型转换
    02_1标识符_关键字_数据类型
    01_3Java Application初步
    01_2Java开发环境的下载 安装 配置
    Mac 安装MySQL
    用 Homebrew 带飞你的 Mac
  • 原文地址:https://www.cnblogs.com/xcsn/p/7500417.html
Copyright © 2011-2022 走看看