责任链模式两种典型实现

责任链模式(Chain of Responsibility)是一种处理请求的模式,它让多个处理器都有机会处理该请求,直到其中某个处理成功为止。

责任链模式解决的问题:避免请求的发送者和接收者之间的耦合关系。

Rxjava的拦截器是典型的责任链例子,同时我们自己实现类似的拦截器功能时,也会用到责任链模式,通过研究Rxjava的源码,总结两种实现方案:

  1. 方案一:List,for循环+返回值(最简单的实现)
  2. 方案二:List,链式+手动调用(Rxjava的实现)

方案一:for循环+返回值

示例代码

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
40
41
42
43
44
public interface Interceptor {
// 返回TRUE,拦截此请求
// 返回null 或 FALSE = 交下一个处理
Boolean intercept(Request request);
}

public class InterceptorA implements Interceptor {
public Boolean intercept(Request request){
// 此拦截器对request做个性化处理
...

// 拦截此请求
return true
// 交下一个拦截器处理
return false
}
}

public class InterceptorChain {

private List<Interceptor> interceptors = new ArrayList<Interceptor>();

public void addInterceptor(Interceptor interceptor){
this.interceptors.add(interceptor);
}

public boolean process(Request request){
for(Interceptor interceptor : interceptors) {
Boolean result = interceptor.intercept(request);
if(result == true) {
return ;
}
}
}

public static void main(String[] args) {
InterceptorChain chain = InterceptorChain();
chain.addInterceptor(new InterceptorA());
chain.addInterceptor(new InterceptorB());

// 处理请求
boolean result = chain.process(new Request("Hello Wrold"));
}
}

类图

时序图

方案二:链式+手动调用

示例代码

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
40
41
42
43
44
45
46
47
48
49
50
51
52
public interface Interceptor {
Response intercept(Chain chain, Request request);
}

public interface Chain {
Response process(Request request);
}

public class InterceptorA implements Interceptor {
Response intercept(Chain chain, Request request){
// 此拦截器对request做个性化处理
...

// 拦截此请求
return null;
// 交下一个拦截器处理,chain 可以理解为下一个链路结点,即下一个拦截器
return chain.process(request);
}
}

public class InterceptorChain implements Chain {

private final List<Interceptor> interceptors = new ArrayList<Interceptor>();
private final int index;

public InterceptorChain(List<Interceptor> interceptors, int index){
this.interceptors = interceptors;
this.index = index;
}

@Override
public Response process(Request request);
if(index >= interceptors.size()) {
// 所有拦截器都已处理完成
return processFinal(request);
}

// 构建下一个执行链路节点
InterceptorChain next = new InterceptorChain(interceptors, index + 1);
Interceptor interceptor = interceptors.get(index);
return interceptor.intercept(next, request);
}

public static void main(String[] args) {

List<Interceptor> interceptors = new ArrayList<Interceptor>();
interceptors.add(new InterceptorA());
interceptors.add(new InterceptorB());

Response response = new InterceptorChain(interceptors, 0).process(new Request("Hello Wrold"));
}
}

类图

时序图

对比

两种方案的最大差别在于:方案二可以实现Request对象处理前的拦截,和处理后的拦截,原理是通过函数的递归调用。

参考

  1. 廖雪峰-责任链
  2. 类图+时序图参考
感谢您的阅读,本文由 刘阳 版权所有。如若转载,请注明出处:刘阳(https://handsomeliuyang.github.io/2021/01/20/%E6%97%A5%E5%B8%B8%E5%AD%A6%E4%B9%A0-%E8%B4%A3%E4%BB%BB%E9%93%BE%E6%A8%A1%E5%BC%8F%E4%B8%A4%E7%A7%8D%E5%85%B8%E5%9E%8B%E5%AE%9E%E7%8E%B0/
群晖:搭建个人和工作的数据中心
Android端的架构设计的演进和思考