行为型模式之责任链模式
抽象处理者(Handler):对请求进行抽象,并定义一个方法以设定和返回对下一个处理者的引用。
具体处理者(Concrete Handler):接到请求后,可以选择将请求处理掉或将请求传递给下一个处理者。
Handler.java
public abstract class Handler { private Handler successor; // 处理方法 public abstract void handleRequest(); public Handler getSuccessor() { return successor; } public void setSuccessor(Handler successor) { this.successor = successor; } }
ConcreteHandler.java
public class ConcreteHandler extends Handler { private String name; public ConcreteHandler(String name) { this.name = name } // 处理请求 public void handleRequest() { System.out.println("当前对象" + this); if (this.getSuccessor() != null) { System.out.println("请求传递给" + this.getSuccessor()); this.getSuccessor().handleRequest(); } else { System.out.println("请求处理" + this.geetSuccessor()); } } @Override public String toString() { return "ConcreteHandler [name=" + name + "]"; } }
Client.java
public class Client { public static void main(String[] args) { Handler h1 = new ConcreteHandler("A"); Handler h2 = new ConcreteHandler("B"); h1.setSuccessor(h2); h1.handleRequest(); } }
运行结果如下所示。
当前对象ConcreteHandler [name=A] 请求传递给ConcreteHandler [name=B] 当前对象ConcreteHandler [name=B] 请求处理null
优点:
- 将请求和处理分开,请求者不知道谁处理的,处理者可以不用知道请求者的全貌。
- 提高系统灵活性。
缺点:
- 降低程序的性能,每个请求都是从链头遍历到链尾,当链比较长的时候,性能会大幅下降。
- 不易调试,由于采用类似递归的方式,调试的时候逻辑比较复杂。
注意:责任链中的节点数量需要控制,避免出现超长链的情况,这就需要设置一个最大节点数量,超过则不允许增加节点,避免无意识地破坏系统性能。
应用场景:
Struts2的核心控件FilterDispatcher是一个Servlet过滤器,该控件就是采用责任链模式,可以对用户请求进行层层过滤处理。责任链模式在实际项目中使用比较多,其典型的应用场景如下:
- 一个请求需要一系列的处理操作。
- 业务流的处理,例如文件审批。
- 对系统进行补充扩展。
摘自:
青岛东合信息技术有限公司 . 设计模式(Java版) . 电子工业出版社,2012,122-128.