美文网首页
OkHttp设计模式剖析(二)责任链模式

OkHttp设计模式剖析(二)责任链模式

作者: YongtaoHuang | 来源:发表于2019-07-13 21:56 被阅读0次

    上一篇 OkHttp设计模式剖析(一)建造者模式

    下一篇 OkHttp设计模式剖析(三)策略模式

    OKHTTP:

    由大名鼎鼎的Square公司开发的网络通信库。

    设计模式:

    软件开发中问题的解决套路。

    责任链模式简介

    定义:使多个对象都有机会处理请求,从而降低收发之间的耦合。将这些对象连成一条责任链,沿着链传递该请求,直到被处理。

    责任链模式将一个复杂的流程拆分给多个对象沿链逐一处理,或者给不同层级的对象沿链分级处理。
    若源代码中有Chain这个词,大概率使用了责任链模式。

    Interceptor(拦截器)类中的责任链模式

    拦截器是一种强大的机制,可以监视、重写和重试调用。

    整个拦截器链包括:所有应用拦截器,OkHttp核心,所有网络拦截器和网络调用者。

    OKHTTP拦截器.png
    ApplicationInterceptor: 应用拦截器
    RetryAndFollowUpInterceptor: 请求重试(从错误中恢复进行重定向 )
    BridgeInterceptor:桥接(从应用程序代码到网络代码的桥梁)
    CacheInterceptor:缓存(来自缓存的请求并将响应写入缓存)
    ConnectInterceptor:连接(打开到目标服务器的连接)
    NetworkInterceptor:网络拦截器
    CallServerInterceptor:链中的最后一个拦截器,它对服务器进行网络调用
    平时使用框架时,只有应用拦截器和网络拦截器可以自定义。

    平时使用OkHttp框架都是用下面的套路:

    OkHttpClient client = new OkHttpClient();
    Request request = new Request.Builder().build();
    Response response = client.newCall(request).execute();
    

    其中client.newCall()返回的是Call的实现类RealCall,然后执行execute()方法时,会调用getResponseWithInterceptorChain()方法,该方法将所有拦截器的返回结果组合成Respose返回的内容,源码如下:

    final class RealCall implements Call {
      RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
        ......//构造函数
      }
    
      @Override 
      public Response execute() throws IOException {
          ......
          Response result = getResponseWithInterceptorChain();
      }
    
      Response getResponseWithInterceptorChain() throws IOException {
        // Build a full stack of interceptors.
        List<Interceptor> interceptors = new ArrayList<>();
        interceptors.addAll(client.interceptors()); // 应用拦截器
        interceptors.add(retryAndFollowUpInterceptor); // 请求重试
        interceptors.add(new BridgeInterceptor(client.cookieJar())); // 桥接
        interceptors.add(new CacheInterceptor(client.internalCache())); // 缓存
        interceptors.add(new ConnectInterceptor(client)); // 连接
        if (!forWebSocket) {
          interceptors.addAll(client.networkInterceptors()); // 网络拦截器
        }
        interceptors.add(new CallServerInterceptor(forWebSocket)); // 网络调用
    
        Interceptor.Chain chain = new RealInterceptorChain(
            interceptors, null, null, null, 0, originalRequest);
        return chain.proceed(originalRequest);
      }
    }
    

    各种拦截器都必须遵循Interceptor接口:

    public interface Interceptor {
      Response intercept(Chain chain) throws IOException;
      interface Chain {
        Request request();
        Response proceed(Request request) throws IOException;
        Connection connection();
      }
    }
    

    拦截器责任链的实现类部分源码,随着index的递增,返回链条中的下一个拦截器。

    public final class RealInterceptorChain implements Interceptor.Chain {
      private final List<Interceptor> interceptors;
    
      public RealInterceptorChain(List<Interceptor> interceptors, StreamAllocation streamAllocation,
          HttpCodec httpCodec, Connection connection, int index, Request request) {
        ......// 构造函数
      }
    
      public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
          Connection connection) throws IOException {
    
        //调用责任链中下一个拦截器
        RealInterceptorChain next = new RealInterceptorChain(
            interceptors, streamAllocation, httpCodec, connection, index + 1, request);
        Interceptor interceptor = interceptors.get(index);
        Response response = interceptor.intercept(next);
    
        return response;
      }
    
    }
    

    基于责任链模式构建的其他代码

    1、Android源码中ViewGroup将事件派发到子View的过程。

    互联网开发流程可以看成责任链设计模式

    不同级别的工程师都可以上手写代码,但是平时负责不同的业务。比如初级工程师负责基础实现,资深工程师负责架构搭建,当然还有(代码中省略),中级工程师负责核心优化,技术总监负责技术管理等。

    public abstract class Engineer {    
        public Engineer nextEngineer;   
        public abstract void handle();  
        public final void work() {
            handle();
            if(null!= nextEngineer) {
                nextEngineer.work();
            }
        }
    }
    
    public class JuniorEngineer extends Engineer{ // 初级工程师
        public void handle() {
            System.out.print("基础实现->");
        }
    }
    
    public class SeniorEngineer extends Engineer { //资深工程师
        public void handle() {
            System.out.print("架构搭建->");
        }
    }
    
    public static void main(String[] args) {
        JuniorEngineer je = new JuniorEngineer();
        SeniorEngineer se = new SeniorEngineer();
        se.nextEngineer = je;
        se.work(); // 输出: 架构搭建->基础实现->
    }
    

    所以,责任链设计模式的核心就是:流水分工

    参考文献

    1、设计模式|菜鸟教程:https://www.runoob.com/design-pattern/design-pattern-tutorial.html
    2、《Android源码设计模式解析与实战》何红辉,关爱民著
    3、隔壁老李头:https://www.jianshu.com/p/82f74db14a18

    上一篇 OkHttp设计模式剖析(一)建造者模式

    下一篇 OkHttp设计模式剖析(三)策略模式

    All is well.

    相关文章

      网友评论

          本文标题:OkHttp设计模式剖析(二)责任链模式

          本文链接:https://www.haomeiwen.com/subject/xmtukctx.html