责任链模式
责任链模式 |
- 责任链模式:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
- 责任链模式的重点在“链”,由抽象类中的方法决定由那个实现类处理该请求,并返回结果,其通用类图如下:
-
- 抽象的处理者Handler实现三个职责:一个是定义一个请求的处理方法handleRequest(),唯一对外开放的方法;一个是定义一个链的编排方法setLevel(),即处理请求的先后顺序,还有设置和获取当前类的处理等级;第三个是定义了具体的请求者必须实现的具体处理任务response()。通用类图的源码如下:
-
public class Request { //定义当前请求的处理等级 private int level; public Request(){ this.level = 1; //默认处理等级为1 } public void setLevel(int level){ this.level = level; } public int getLevel(){ return this.level; } } public abstract class Handler { private Handler nextHandler; private int level; protected void setNextHanlder(Handler handler){ this.nextHandler = handler; } //模板方法,判断请求级别和当前处理的级别 public final String handlerRequest(Request request){ if(request.getLevel() == this.level) return response(request); else{ if(this.nextHandler != null) return this.nextHandler.handlerRequest(request); else return "请求处理失败"; } } protected int getLevel(){ return this.level; } protected void setLevel(int level){ this.level = level; } //抽象处理方法,具体在子类中实现 protected abstract String response(Request request); } public class ConcreteHandler1 extends Handler{ @Override protected String response(Request request) { // TODO Auto-generated method stub return "第一个处理者处理请求"; } } public class ConcreteHandler2 extends Handler{ @Override protected String response(Request request) { // TODO Auto-generated method stub return "第二个处理者处理请求"; } } public class Client { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Request request = new Request(); //request.setLevel(3); Handler handler1 = new ConcreteHandler1(); Handler handler2 = new ConcreteHandler2(); handler1.setLevel(1); handler2.setLevel(2); handler1.setNextHanlder(handler2); System.out.println(handler1.handlerRequest(request)); } }
责任链模式的优缺点 |
优点:责任链模式的优点是将请求和处理分开,请求者可以不用知道谁去处理,处理者不用知道请求的全貌,两者解耦,提高系统灵活性。
缺点:性能问题,每个请求都是从链头遍历到链尾,当链较长时,性能会下降;调试不方便,当链较长时,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂。
最佳实践 |
在类图中Handler是抽象类,融合了模板方法模式,每个实现类只要实现response请求处理方法。通过融合模板方法模式,各个实现类只需要关注自己的业务逻辑,父类决定请求的具体处理类,即父类实现了请求的传递功能,子类实现请求的处理,符合单一职责原则,各个实现类只完成一个动作或逻辑,也就是只有一个原因引起类的变化。
责任链屏蔽了请求的处理过程,只需把请求抛给责任链的第一个处理者,不需要知道具体谁来处理请求,这是责任链模式的核心,同时责任链也可以作为一种补救措施。当随着请求的增加,可以添加对新增请求的处理类,上层的调用保持不变。如银行开始只提供人民币的服务,当业务增加需要同时支持对欧元和美元请求的处理。其可以采取责任链模式,其通用类图如下: