一.介绍
责任链模式(Chain of Responsibility Pattern)。属于行为型模式。它使多个对象都有机会处理请求,从而避免发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
二.实现
举个例子,在一所银行里,有几个级别的员工,柜员、主管、经理。如果有人来存款,柜员只能处理10000元以内的取款业务,超出了就只能传递给他的上级主管去处理。主管只能处理100000元的业务,超出了就只能传递给他的上级经理去处理。在使用责任链模式前,试一下用普通的方式去实现。
public static void WithDrawMoney(decimal amount) { // 柜员处理 if (amount < 10000) { Console.WriteLine("柜员提取的金额"); } // 主管处理 else if (amount < 100000) { Console.WriteLine("主管提取的金额"); } else { Console.WriteLine("经理提取的金额"); } }
用这种 if / else 的方式,如果新增了一个级别的员工,处理起来会很麻烦,也违背开闭原则。而且,处理业务必须从最下级开始,限制高级员工的条件,如经理就处理不了10000元以内的业务。使用责任链模式可以解决这个问题。
//抽象处理者 public abstract class Handler { protected Handler nextHandler; //设置下一级处理人 public void SetHandler(Handler handler) { this.nextHandler = handler; } public abstract void HandleRequest(decimal amount); } //柜员 public class Teller : Handler { public override void HandleRequest(decimal amount) { if (amount < 10000) { Console.WriteLine("柜员提取的金额:"+ amount); } else if (this.nextHandler != null) { Console.WriteLine("柜员无法处理,转主管"); nextHandler.HandleRequest(amount); } } } //主管 public class Supervisor : Handler { public override void HandleRequest(decimal amount) { if (amount < 100000) { Console.WriteLine("主管提取的金额:" + amount); } else if (this.nextHandler != null) { Console.WriteLine("主管无法处理,转经理"); nextHandler.HandleRequest(amount); } } } //经理 public class BankManager : Handler { public override void HandleRequest(decimal amount) { Console.WriteLine("银行经理提取的金额:" + amount); } } //调用 public static void Main(string[] args) { Handler teller = new Teller();//柜员 Handler supervisor = new Supervisor();//主管 Handler bankManager = new BankManager();//经理 teller.SetHandler(supervisor);//定义柜员上级为主管 supervisor.SetHandler(bankManager);//定义主管上级为经理 // Console.WriteLine("柜员处理不同金额的业务"); Console.WriteLine("客户存9000"); teller.HandleRequest(9000); Console.WriteLine(); Console.WriteLine("客户存90000"); teller.HandleRequest(90000); Console.WriteLine(); Console.WriteLine("客户存150000"); teller.HandleRequest(150000); Console.WriteLine(); // Console.WriteLine("柜员请假,业务都由主管处理"); Console.WriteLine("客户存9000"); supervisor.HandleRequest(9000); Console.WriteLine(); Console.WriteLine("客户存90000"); supervisor.HandleRequest(90000); Console.WriteLine(); Console.WriteLine("客户存150000"); supervisor.HandleRequest(150000); Console.WriteLine(); }
三.总结
优点:
1.降低了请求的发送者和接受者之间的耦合。
2.把多个条件判断分散到各个处理类中,使得代码更加清晰,责任更加明确。
缺点:
1.在找到正常的处理对象之前,所有的条件判断都要执行一遍,当责任链过长时,会引起性能问题。
2.可能导致某个请求不被处理。