责任链模式定义如下:
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

责任链的核心在”链“上,”链“是由多个处理者ConcreteHandler 组成的,其父类Handler 实现如下 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public abstract class Handler { private Handler nextHandler;
public final Response handleRequest(Request request) { Response response; if (this.getHandlerLever().equals(request.getRequestLevel())) { response = this.doSth(request); } else { if (this.nextHandler != null) { response = this.nextHandler.handleRequest(request); } else { System.out.println("handler not found."); response = null; } } return response; }
public void setNext(Handler handler) { this.nextHandler = handler; }
protected abstract Level getHandlerLever();
protected abstract Response doSth(Request request);
|
抽象父类Handler 实现3 个职责:
- 定义一个请求的处理方法handleRequest, 唯一对外开放的方法
- 定义一个链的编排方法setNext
- 定义具体的实现子类必须实现的两个方法:一是自己能够处理的级别getHandlerLever 和具体的业务实现 doSth
下面是三个具体的实现子类:
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class ConcreteHandler1 extends Handler { @Override protected Level getHandlerLever() { return Level.ONE; }
@Override protected Response doSth(Request request) { String body = request.getBody(); System.out.println("request is: " + body + " I'm handler1" ); return new Response(body); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class ConcreteHandler2 extends Handler { @Override protected Level getHandlerLever() { return Level.TWO; }
@Override protected Response doSth(Request request) { String body = request.getBody(); System.out.println("request is: " + body + " I'm handler2"); return new Response(body); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class ConcreteHandler3 extends Handler { @Override protected Level getHandlerLever() { return Level.THREE; }
@Override protected Response doSth(Request request) { String body = request.getBody(); System.out.println("request is: " + body + " I'm handler3"); return new Response(body); } }
|
在处理者中涉及三个类:Level类负责定义请求和处理级别,Request类负责封装请 求,Response负责封装链中返回的结果,这三个类都需要根据实际业务来定:
1 2 3 4
| public enum Level { ONE, TWO, THREE; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class Request { private Level level;
private String body;
public Request(Level level, String body) { this.level = level; this.body = body; }
public Level getRequestLevel() { return this.level; }
public String getBody() { return body; } }
|
1 2 3 4 5 6 7
| public class Response { private String message;
public Response(String message) { this.message = message; } }
|
下面是实际的应用,先构造不同级别的请求,再构造链条,最后用第一个处理器来处理任意一个请求均可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Client { public static void main(String[] args) { Request request1 = new Request(Level.ONE, "1"); Request request2 = new Request(Level.TWO, "22"); Request request3 = new Request(Level.THREE, "333");
Handler handler1 = new ConcreteHandler1(); Handler handler2 = new ConcreteHandler2(); Handler handler3 = new ConcreteHandler3(); handler1.setNext(handler2); handler2.setNext(handler3);
handler1.handleRequest(request2); handler1.handleRequest(request3); handler1.handleRequest(request1); } }
|
控制台打印结果:
1 2 3
| request is: 22 I'm handler2 request is: 333 I'm handler3 request is: 1 I'm handler1
|
在实际应用中,一般会有一个封装类对责任模式进行封装,也就是替代Client类,直接 返回链中的第一个处理者,具体链的设置不需要高层次模块关系,这样,更简化了高层次模 块的调用,减少模块间的耦合,提高系统的灵活性。
优点
责任链模式非常显著的优点是将请求和处理分开。请求者可以不用知道是谁处理的,处 理者可以不用知道请求的全貌(例如在J2EE项目开发中,可以剥离出无状态Bean由责任链处 理),两者解耦,提高系统的灵活性。
缺点
责任链有两个非常显著的缺点:一是性能问题,每个请求都是从链头遍历到链尾,特别 是在链比较长的时候,性能是一个非常大的问题。二是调试不很方便,特别是链条比较长, 环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂。
链中节点数量需要控制,避免出现超长链的情况,一般的做法是在Handler中设置一个 最大节点数量,在setNext方法中判断是否已经是超过其阈值,超过则不允许该链建立,避免 无意识地破坏系统性能。