职责链模式

摘自: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();
    }

结果显示如下:

原文地址:https://www.cnblogs.com/nygfcn1234/p/3396307.html