责任链模式及OkHttp中的实现

作者: 花京院典明 | 来源:发表于2016-12-25 12:42 被阅读944次

责任链模式及OkHttp中的实现

责任链模式

责任链模式是对一个事件的处理方法,所有能对事件进行处理的对象按顺序形成一个链表.事件经过链表中每个处理对象轮流处理.如果有返回值.则返回也是顺着这条链表反向返回.这个链表是先进后出模式.

  • 在现实中的责任链模型之一就是网络连接.对与程序猿而言,七层或五层的网络连接模型是肯定知道的.

当一个网络请求发出时,需要经过应用层->传输层->网络层->连接层->物理层

收到响应后正好反过来,物理层->连接层->网络层->传输层->应用层

在请求经过各层时,由每层轮流处理.每层都可以对请求或响应进行处理.并可以中断链接,以自身为终点返回响应

  • 另一个现实模型就是Web服务器的请求缓存

一个请示从客户端发送到Web服务器需要经过客户端->中间服务器->反向代理->Web端缓存(如Redis)->Web数据库

除了Web数据库是请求的点外,中间所有层都可以缓存数据.如果有缓存时会终止请求,以自身为终点返回数据.

如果途经的层没有缓存,则会在收到下一级的返回的数据时对数据进行缓存.然后返回上一层.

在设计模式中,负责链模式就是对这种顺序处理事件的行为的抽象,通过接口来定义处理事件的方法.顺序分发/处理事件.

  • 每个责任人实现相同的接口,处理一个事件对象
  • 让事件对象责任人之间顺序传递
  • 事件的处理结果的返回是逆序的
  • 责任链中的每个责任人都可以有权不继续传递事件,以自身为终点处理事件返回结果

OkHttp中的责任链模式

Okhttp中,Intercepter就是典型的责任链械的实现.它可以设置任意数量的Intercepter来对网络请求及其响应做任何中间处理.比如设置缓存,Https的证书验证,统一对请求加密/防串改,打印自定义Log,过滤请求等.

interface Intercepter{
Response response chain(Chain chain);
}

这个接口很简单,拿到Chain对象.最后返回个Response,那这个对象是什么鬼??

它有两个重要的方法
public Request getQuest()public Response process(Request quest)
拿到请求及设置请求拿到响应.
一般的实现是先拿到请求.然后对请求做一番蹂躏,然后process一下,拿到Response,折腾一下.然后return

Response response chain(Chain chain){
  Requset quest = chian.getRequset()
  ooxx(request);
  Response response = chian.process(quest);
  xxoo(response);
  return response;
}

或许它不知道,Resquse其实是被上家ooxx过的,Respnse也是被下家xxoo过的.

具体的实现可以去看一下源码,我这里就写一下自己理解的超简单的实现

public class Okhttp {
private List<Intercepter> mIntercepters=new LinkedList<>();
private Request mRequest;
private int mIndex;
private Callback mCallback;
private Chain mChain=new Chain();
private Intercepter mNetIntercepter =new Intercepter() {
@Override
public Response chain (Chain chain) {
  //这里是真实的发送网络请求
  return 网络请示的响应;
  }
};

/**
* 添加拦截器,后加的放最前面
* @param intercper 拦截器
*/
public void addIntercepter(Intercepter intercper){
  mIntercepters.add(0, intercper);
}

/**
* OkHttp请求的入口
* @param request 请示
* @param callback 回调
*/
public void execute(Request request ,Callback callback){
  mCallback=callback;
  mIndex=0;
  mRequest=request;
  new Thread(new Runnable() {
  @Override
  public void run () {
    Response response=mChain.process(mRequest);
    mCallback.onResponse(response);
    }
  }).start();
}

/**
* 定义的一个类用与递归的方式完成责任链发送请求获取响应
*/
private class Chain {
public Request getRequest(){
  return mRequest;
}

/**
* 顺序获取拦截器,传递chain对象给拦截器,获取响应
* @return 请求的响应
*/
private Response getResponse () {
  Intercepter intercepter = mIntercepters.get(mIndex);
  mIndex++;
  return intercepter.chain(this);
}

/**
* 如果责任链没走完,则顺序从责任链中获取拦截器,处理请求
* 否则由真正的负责网络请求的拦截器处理请求
* @param request 请求
* @return 响应
*/
Response process(Request request){
  mRequest=request;
  if (mIndex>=mIntercepters.size()){
    return Okhttp.this.mNetIntercepter.chain(this);
  }else{
    return getResponse();
  }
}
}
}

不得不说程序猿写文章真是容易骗字数.我已经极力在简化了.代码还是差不多上百行.

应该写得够简单吧.重点也就几个

  1. 内部有个处理真实网络请求的Intercepter,做为最后的接盘侠.
  2. 返回响应的是intercepter.chain(this),如果这个拦截器调用了chainprocess()方法就形成递归,否则就是终断了请求的传递
  3. 整个责任链的传递都是同步的.整体在子线程运行,最后通过回调返回响应.

还有一个很经典的实现就是Android的事件分发机制.这里我就不贴代码骗字数了.网上随便一找一堆.

责任链模式的用途

当业务逻辑需要形成一个事件处理流时,就可以考虑使用责任链模式.通过接口来规范中间环节的行为,专注与事件流的传递.可以随意扩展及调整中间环节.

我在实际业务中的有一个场景中使用了责任链模式.(当时使用的时候其实并不清楚)

  1. 在一个列表中可以弹出一个筛选菜单,菜单项是不定的.某些项选择后可以增加更多的选项条目
  2. 选项条目类型不同.有单选,多选,输入等.
  3. 点击完成时才把所有筛选条目形成对应的网络请求参数

实际处理起来很简易.定义了两个类

interface ParamsSetAble{
void setParams(NetParams params);
}

public class NetParams{}

每个条目实现ParamsSetAble接口用与设置参数.

NetParams类用与收集参数,最后转换成网络请求所用的格式

当点击完成时,遍历所有的条目,传递NetParams对象.最后把这个对象传递给网络请求的类.

在传递时进行可以进行参数检查,错误时可以中断传递,提示错误.我这里是通过手动抛异常来中断的.在外部统一catch处理.如果用Rxjava可以不用catch,在onError里统一管理.如Observer.error(new 自定义异常(中断提示信息))

相关文章

  • 责任链模式及OkHttp中的实现

    责任链模式及OkHttp中的实现 责任链模式 责任链模式是对一个事件的处理方法,所有能对事件进行处理的对象按顺序形...

  • 责任链模式与 OkHttp

    什么是责任链模式 OkHttp中责任链模式的实现 一、什么是责任链模式 使多个对象都有机会处理请求,从而避免了请求...

  • Okhttp3 Interceptor(三)

    前言 OkHttp 中的 Interceptor 是通过责任链模式来设计的, 责任链模式参考: 责任链模式 , 至...

  • BRouter 入门

    实现 整体实现参考OkHttp的interceptor责任链模式,支持Router跳转中的认证,拦截,重定向,AB...

  • 高仿okhttp手写责任链模式

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

  • OkHttp设计模式剖析(三)策略模式

    上一篇 OkHttp设计模式剖析(二)责任链模式 下一篇 OkHttp设计模式剖析(四)享元模式 OKHTTP...

  • 责任链模式

    概念   说到责任链模式,我就想起了okHttp中设置拦截器的时候了,今年、中外、开花,关注。  其实责任链就是将...

  • okhttp网络框架源码浅析(二)

    okhttp网络框架源码浅析(一) interceptors责任链 不清楚责任链设计模式,可以先了解一下责任链设计...

  • Java设计模式之责任链模式

    一、责任链模式的定义二、责任链模式的使用场景三、责任链模式UML类图四、责任链模式具体实例五、责任链模式代码实现 ...

  • OkHttp源码之RetryAndFollowUpInterce

    之前在上一篇文章okhttp源码之责任链模式中有提到过,okhttp的所有功能都是通过拦截器来实现的,就是我们今天...

网友评论

    本文标题: 责任链模式及OkHttp中的实现

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