首页 职责链模式
文章
取消

职责链模式

定义

将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。在这之上每个接收对象承担自己独有的处理职责(或者说每个接口对象能实现的功能应该不同)

实现方式

链表式

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 拦截器,这两算是职责链模式的经典应用了,它两的关系如下图:

有一点需要提示的是:无论是过滤器还是拦截器,它两都可以对请求和响应进行拦截。

具体源码不在这剖析。

本文由作者按照 CC BY 4.0 进行授权

状态模式

积分体系设计