定义
将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。在这之上每个接收对象承担自己独有的处理职责(或者说每个接口对象能实现的功能应该不同)
实现方式
链表式
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
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* 接收对象抽象类
*/
public abstract class Handler {
protected Handler successor = null;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public final void handle() {
boolean handled = doHandle();
if (successor != null && !handled) {
successor.handle();
}
}
protected abstract boolean doHandle();
}
/**
* 处理链
*/
public class HandlerChain {
private Handler head = null;
private Handler tail = null;
public void addHandler(Handler handler) {
handler.setSuccessor(null);
if (head == null) {
head = handler;
tail = handler;
return;
}
tail.setSuccessor(handler);
tail = handler;
}
public void handle() {
if (head != null) {
head.handle();
}
}
}
如何使用:调用 HandlerChain 对象的 handle() 方法,就会启动这条处理链运行,直到遇到一个能处理的接收对象,然后程序结束。
数组式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 接收对象接口
*/
public interface IHandler {
boolean handle();
}
public class HandlerChain {
private List<IHandler> handlers = new ArrayList<>();
public void addHandler(IHandler handler) {
this.handlers.add(handler);
}
public void handle() {
for (IHandler handler : handlers) {
boolean handled = handler.handle();
if (handled) {
break;
}
}
}
}
虽然数组的实现方式相比链表的实现方式粗糙些,但是足够简单,每次调用 HandlerChain 对象的 handle() 方法就去遍历所有的接收对象数组,直到遇到能处理的接收对象。
职责链模式变体
上面的几种实现方式是:遇到一个能处理的接受对象就马上停止执行链,实际上它还有一种变体,即每个接收对象都会取处理请求,反而这种变体的实现应用的更多,比较在一些常见的权限校验框架中就用的比较多。实现方式很简单,在执行链的执行过程中不对接收对象做条件限制,让它一直执行就可以了。
不得不说,像模板模式、策略模式和职责链模式的这种,它们更多的被应用在框架中,毕竟它们的这种实现方式本身就是一种框架,比如职责链模式就是定义了一个执行方式,比如执行链,这样在定义新的接收对象类的时候我们压根不用去修改框架代码,正好符合变化的交给自定义,其余的所有工作由框架包揽。
应用场景
过滤器 和 Spring MVC 拦截器,这两算是职责链模式的经典应用了,它两的关系如下图:
有一点需要提示的是:无论是过滤器还是拦截器,它两都可以对请求和响应进行拦截。
具体源码不在这剖析。