一、介绍
责任链模式是一种对象的行为模式。在责任链模式里,为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。
实现方式:
- 使用链表的方式进行串联,将多个handler串联起来;
- 使用list方式,循环执行list中的每个handler;
优点:
- 降低耦合性,发送者,发送处理者,接收者三者进行了解耦;
- 简化对象,对象不需要知道链的结构;
- 增强了灵活性,使得增加和删除请求变得容易;
缺点:
- 不能保证请求一定被接收;
- 可能不容易观察运行时的特征,有碍于除错;
二、使用
1. okhttp中的拦截链- list实现
okhttp中的interceptorChain的调用使用list存放interceptor,并通过递归的方式进行调用;
入口:
RealCall中的getResponseWithInterceptorChain()方法中创建InterceptorChain,然后调用chain.proceed(request: Request)开启责任链;
类图:
其中RealInterceptorChain继承Interceptor中的Chain,Chain接口可以携带实现的Interceptor所需要的相应内容;
RealInterceptorChain $proceed(request: Request)开启责任链模式:
@Throws(IOException::class)
override fun proceed(request: Request): Response {
...
// Call the next interceptor in the chain.
// 浅拷贝一个RealIntercepterChain,主要目的将当前index向后一一位
val next = copy(index = index + 1, request = request)
// 获取当前index的Intercepter
val interceptor = interceptors[index]
// 执行当前Intercepter的intercepter(chain: Chain)方法,并传入之前浅拷贝的Chain;
@Suppress("USELESS_ELVIS")
val response = interceptor.intercept(next) ?: throw NullPointerException(
"interceptor $interceptor returned null")
return response
}
当初始化时,index=0,interceptors[0]为MyAppInterceptor, 以okhttp给出的例子来作为MyAppInterceptor;
MyAppinterceptor是okhttp给出的Application Interceptor,和Network Interceptor的最大区别来自于位置不同,所能够获取的request和response的不同;
class MyAppInterceptor: Interceptor{
override fun intercept(chain: Interceptor.Chain): Response {
// do something
// 此时传入的Chain中的index为list中下一个interceptor的索引;
// 此时直接继续调用RealInterceptorChain$process()直到CallServerInterceptor $intercept(chain: Interceptor.Chain);
return chain.proceed(chain.request())
}
}
最后到CallServerInterceptor i n t e r c e p t ( c h a i n : I n t e r c e p t o r . C h a i n ) , 不 再 调 用 R e a l I n t e r c e p t o r C h a i n intercept(chain: Interceptor.Chain),不再调用RealInterceptorChain intercept(chain:Interceptor.Chain),不再调用RealInterceptorChainprocess(),直接返回response;
class CallServerInterceptor(private val forWebSocket: Boolean) : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
// do something ...
var response = responseBuilder
.request(request)
.handshake(exchange.connection.handshake())
.sentRequestAtMillis(sentRequestMillis)
.receivedResponseAtMillis(System.currentTimeMillis())
.build()
// do something ...
return response
}
}
kotlin使用小技巧:
// interceptor中增加invoke函数好,则可以直接使用lambda方法初始化;
companion object {
/**
* Constructs an interceptor for a lambda. This compact syntax is most useful for inline
* interceptors.
*
* ```
* val interceptor = Interceptor { chain: Interceptor.Chain ->
* chain.proceed(chain.request())
* }
* ```
*/
inline operator fun invoke(crossinline block: (chain: Chain) -> Response): Interceptor =
Interceptor { block(it) }
}
2. 链表实现;
具体实现方法如下所示:
public class FilterChain {
Filter head = null;
public void addFilter(Filter filter) {
Filter curr = head;
while (curr != null && curr.nextFilter != null) {
curr = curr.nextFilter;
}
if (curr == null) curr = filter;
else curr.nextFilter = filter;
}
public void execute() {
head.process();
}
}
FilterChain保留了一个单向链表的起始点,每次增加需要遍历当前链表找到最后结点插入数据;
public abstract class Filter {
Filter nextFilter;
void process() {
if (nextFilter == null) return;
nextFilter.process();
}
}
引用:
https://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html