zoukankan      html  css  js  c++  java
  • 职责链模式

    摘自:http://www.cnblogs.com/saville/archive/2012/09/04/2670966.html

    Chain of Responsibility模式的应用场合在于“一个请求可能有多个接受者,但是最后真正的接受者只有一个”,只有这时候请求发送者与接受者的耦合才有可能出现“变化脆弱”的症状,职责链的目的就是将二者解耦,从而更好地应对变化。

      应用了Chain of Responsibility模式后,对象的职责分派将更具灵活性。我们可以在运行时动态添加/修改请求的处理职责。

      当我们要新增一个DHandler处理请求,就不需再改原来的代码了,遵从了开放封闭原则。这样我们的程序就更赋予变化,更有变化的抵抗力。Handler类本身继承自BaseHandler类型,又包含了一个BaseHandler类型的对象,这点类似Decorator模式。这种模式在处理UI的消息时很常用,但实际上Windows消息循环还是硬编码的结构。因为效率上的考虑,Windows消息循环是哪个对象 有一个请求,则直接到达处理函数的地址。如果链条上的对象多了,而真正处理的函数在链条后部分,效率会很低下。因此我们在使用这种模式的时候更适合业务流 程,即对性能要求不是特别高的情况更加常用。

    职责链模式将多个处理对象连接形成一条链,并沿着该链传递需处理的请求,直到有一个对象被处理或是请求被传递到链的末尾为止。该模式将请求与处理解耦,可以动态的增减处理职责,增加了灵活性。其结构图如下:

    Handler定义了处理对象的接口,往往通过它来实现后继的职责链。

    ConcreteHandler实现Handler定义的接口,定义了不同的处理对象。如果该对象能处理待处理请求,那就进行处理并完成请求在职责链上的传递,如果无法处理,那就转交给后继的处理对象处理。

    Client负责向职责链上的处理对象提交请求。

    典型的示例有:员工请假处理流程,银行贷款申请处理流程等。

    假设银行对用户贷款的审批分成三个处理层级:金额小于2万元的可由普通员工审批,金额大于等于2万元且小于5万元的由副经理审批,而金额大于等于5万元的则必须由经理来审批。

    首先定义申请贷款的基本信息。

        public class Loan
        {
            public Loan(string name, int amount)
            {
                Name = name;
                Amount = amount;
            }
    
            public string Name { get; set; }
            public int Amount { get; set; }
        }

    接着定义普通员工、副经理以及经理的处理对象。

        public class Employee
        {
            public Employee Next { get; set; }
    
            public virtual void Dispose(Loan loan)
            {
                if (loan.Amount < 20000)
                {
                    Console.WriteLine("Disposed by ordinary employee.");
                }
                else if (Next != null)
                {
                    Next.Dispose(loan);
                }
                else
                {
                    Console.WriteLine("Can't dispose load.");
                }
            }
        }
    
        public class DeputyManager : Employee
        {
            public override void Dispose(Loan loan)
            {
                if (loan.Amount < 50000)
                {
                    Console.WriteLine("Disposed by deputy manager.");
                }
                else if (Next != null)
                {
                    Next.Dispose(loan);
                }
                else
                {
                    Console.WriteLine("Can't dispose load.");
                }
            }
        }
    
        public class Manager : Employee
        {
            public override void Dispose(Loan loan)
            {
                Console.WriteLine("Disposed by manager.");
            }
        }

    调用

        static void Main(string[] args)
        {
            Employee employee = new Employee();
            DeputyManager deputyManager = new DeputyManager();
            Manager manager = new Manager();
            employee.Next = deputyManager;
            deputyManager.Next = manager;
            Loan loan = new Loan("Jim", 1000);
            Console.WriteLine("Jim's loan:");
            employee.Dispose(loan);
            loan = new Loan("Jack", 30000);
            Console.WriteLine("Jack's loan:");
            employee.Dispose(loan);
            loan = new Loan("Tom", 300000);
            Console.WriteLine("Tom's loan:");
            employee.Dispose(loan);
            Console.ReadLine();
        }

    结果显示如下:

  • 相关阅读:
    对图像去噪的拙见
    FastIV图像处理
    常见小波变换开源代码
    暗通道去雾与自适应直方图均衡去雾之比较
    CUDA编程札记
    一种极快速去模糊效应图像细节增强及其应用
    基于稀疏表示的人脸识别
    C# Update Oracle Blob字段的一个错误问题
    ArcEngine开发过程中 Erase工具调用失败的解决办法
    模型化空间分析原型系统开发
  • 原文地址:https://www.cnblogs.com/nygfcn1234/p/3396307.html
Copyright © 2011-2022 走看看