摘自: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(); }
结果显示如下: