Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
责任链模式含义
阅读OkHttp源码的过程中,我发现它在处理拦截器的过程中非常的巧妙,结合了责任链模式,将Request
以链路的方式传递下去,再将Response
以方向链路传递上来。
责任链模式(Chain of Responsibility)使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
接下来我们模仿OkHttp来写个责任链模式,处理请求和响应。
实例
需求:一个Request
请求,需要经过Log
、Header
、Connect
和Call
四个流程,每个流程都会单独对Request
进行处理,最终从流程的末端获取Response
。
具体流程如上图所以,Chain
作为链条,驱动着Request
请求的开始,同时也是最终拿到Response
的对象。
- 实线部分为完整的一个责任链流程,
Chain
发起,经过Logger
->Header
->Connect
->Call
,等到Call
处理完结果,再将结果方向传递上去,依次经过Call
->Connect
->Header
->Logger
->Chain
。 - 虚线部分为中途被某一个对象提前消费返回,比如在
Header
步骤出现异常,生成一个空的Response
返回,那么请求流程就变为Chain
->Logger
->Header
,返回流程则为Header
->Logger
->Chain
;这就是责任链模式的魅力,链中任何一个对象都可以提前消费并返回,而且不影响链路的正常执行。
下面用代码展示下。
编码
/**
* [Chain]对象用来发起请求,并且接收最终的结果
*/
class Chain(private val interceptorList: List<Interceptor>, private val index: Int, val request: Request) {
/**
* 依次调用链对象处理方法
*/
fun process(request: Request): Response {
// 同样使用index作为下标,用来依次调用链中对象
val next = Chain(interceptorList, index = this.index + 1, request)
val interceptor = interceptorList[index]
return interceptor.intercept(next)
}
}
/**
* [Request]
*/
class Request(var msg: String) {
fun buildRequest(msg: String) = Request(msg)
}
/**
* [Response]
*/
class Response(val msg: String) {
fun buildResponse(msg: String) = Response(msg)
}
上面主要定义Chain
、Request
和Response
/**
* [Interceptor]对象用来处理链中对象的逻辑
*/
interface Interceptor {
fun intercept(chain: Chain): Response
}
class LoggerInterceptor : Interceptor {
override fun intercept(chain: Chain): Response {
val request = chain.request
println("logger request: ${request.msg}")
val response = chain.process(request.buildRequest("logger"))
println("logger response: ${response.msg}")
return response.buildResponse("logger")
}
}
class HeaderInterceptor : Interceptor {
override fun intercept(chain: Chain): Response {
val request = chain.request
println("header request: ${request.msg}")
val response = chain.process(request.buildRequest("header"))
println("header response: ${response.msg}")
return response.buildResponse("header")
}
}
class ConnectInterceptor : Interceptor {
override fun intercept(chain: Chain): Response {
val request = chain.request
println("connect request: ${request.msg}")
val response = chain.process(request.buildRequest("connect"))
println("connect response: ${response.msg}")
return response.buildResponse("connect")
}
}
class CallInterceptor : Interceptor {
override fun intercept(chain: Chain): Response {
val request = chain.request
println("call request: ${request.msg}")
println()
val response = Response("call")
println("call response: ${response.msg}")
return response
}
}
定义Interceptor
基类和四个链对象;
fun main() {
val interceptorList = mutableListOf<Interceptor>()
interceptorList += LoggerInterceptor()
interceptorList += HeaderInterceptor()
interceptorList += ConnectInterceptor()
interceptorList += CallInterceptor()
val request = Request("init")
val chain = Chain(interceptorList, 0, request)
chain.process(request)
}
将四个链对象传入Chain
中,然后发起请求,看下Log:
logger request: init
header request: logger
connect request: header
call request: connect
call response: call
connect response: call
header response: connect
logger response: header
通过Log我们就能很清楚的看到每个链中对象的执行过程,按照顺序依次进入对象的执行过程,最后再反向将Response
传递上去。