高仿okhttp手写责任链模式

okhttp使用的设计模式面试的时候经常被问到,其中里面最多的建造者模式和责任链模式
其中责任链模式也是okhttp的核心。

  • 创建一系列拦截器,并将其放入到一个拦截器list当中。
  • 创建一个拦截器链RealInterceptorChain对象,并执行拦截器的proceed方法(创建下一个拦截器)。
  • 在发起请求前对request进行处理。
  • 调用下一个拦截器,获取response。
  • 对response进行处理,返回给上一个拦截器。
Response response = getResponseWithInterceptorChain(); 通过拦截器获取一个响应。
007S8ZIlly1ghbgbi291zj30is0ieq45.jpg

okhttp具体实现如何,主要代码:
RealInterceptorChain

 public Response proceed(Request request, Transmitter transmitter, @Nullable Exchange exchange)
      throws IOException {
    if (index >= interceptors.size()) throw new AssertionError();

    calls++;

    // If we already have a stream, confirm that the incoming request will use it.
    if (this.exchange != null && !this.exchange.connection().supportsUrl(request.url())) {
      throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
          + " must retain the same host and port");
    }

    // If we already have a stream, confirm that this is the only call to chain.proceed().
    if (this.exchange != null && calls > 1) {
      throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
          + " must call proceed() exactly once");
    }

    // Call the next interceptor in the chain.
    RealInterceptorChain next = new RealInterceptorChain(interceptors, transmitter, exchange,
        index + 1, request, call, connectTimeout, readTimeout, writeTimeout);
    Interceptor interceptor = interceptors.get(index);
    Response response = interceptor.intercept(next);

具体拦截器代码:调用proceed方法。

@Override public Response intercept(Chain chain) throws IOException {
   Response networkResponse = chain.proceed(requestBuilder.build());
}

手动实现:

interface  InterceptorCallBack {

    fun handle(chain: Chain):String? //类似于intercept方法

    interface Chain {
        fun proceed(requestStr: String?): String?
        fun getRequest():String?
    }
}

拦截器调度中心


package com.learn.ckx_test.response_chain_demo

//管理类
class RealInterceptorChain:InterceptorCallBack.Chain {

    private val mList: MutableList? = ArrayList()
    private var index = 0
    private var lastResponse:String? = ""

    fun addLeaders(leader: InterceptorCallBack) {
        mList?.add(leader)
    }

    fun removeLeaders(leader: InterceptorCallBack) {
        mList?.remove(leader)
    }

    override fun proceed(request: String?): String? {
        lastResponse = request
        println("index的值:$index")
        if (mList == null ||mList.size == 0)  return lastResponse
        if (index >= mList.size) return lastResponse

        val nextIntIterator = mList[index]

        index ++
        println("lastResponse的值:$lastResponse")

        lastResponse = nextIntIterator.handle(this)
        return lastResponse
    }

    override fun getRequest(): String? {
        return lastResponse
    }
}

拦截器1:

class InterceptorOne : InterceptorCallBack {
    
    override fun handle(chain: InterceptorCallBack.Chain): String? {
        println("我Leader1处理过了,传给下一个拦截器")
        val request = chain.getRequest()
        val result = request + "我Leader1处理过了,传给下一个拦截器"
        val response = chain.proceed(result)
        return response
    }
}

拦截器2:

class InterceptorTwo : InterceptorCallBack {
    
    override fun handle(chain: InterceptorCallBack.Chain): String? {

        println("我Leader2处理过了,传给下一个拦截器")
        val request = chain.getRequest()
        val result = request + "我Leader2处理过了,传给下一个拦截器"
        val response = chain.proceed(result)
        return response
    }
}

测试:

  @JvmStatic
    fun main(args: Array) {
        val leaderManager = RealInterceptorChain();//传递下发任务可执行等级
        leaderManager.addLeaders(InterceptorOne());
        leaderManager.addLeaders(InterceptorTwo());
        val result = leaderManager.proceed("开始请求了");//开始执行
        println("最后的结果是:$result")

    }

传入一个requet请求,一定要注意返回response,每个拦截器都能对请求进行处理,处理之后把结果返回给下一个拦截器。
测试结果:

ndex的值:0
lastResponse的值:开始请求了
我Leader1处理过了,传给下一个拦截器
index的值:1
lastResponse的值:开始请求了我Leader1处理过了,传给下一个拦截器
我Leader2处理过了,传给下一个拦截器
index的值:2
最后的结果是:开始请求了我Leader1处理过了,传给下一个拦截器我Leader2处理过了,传给下一个拦截器

注意:

  • 一般网上的例子都是基于递归,在递归里面进行判断是否要往下进行,实际okhttp是在调度中心,根据拦截器集合index判断是否是最后一个拦截器,来终止往下传递。
  • 拦截器传递到最后一定要返回执行后的结果,就像okhttp使用责任链模式执行各个拦截器功能之后,最后一定要返回response才能完整。

你可能感兴趣的:(高仿okhttp手写责任链模式)