一、基本概念

1、定义

多个对象都有机会处理请求,将这些对象连成一个链,将请求沿着这条链传递,直到有对象处理为止。

2、使用场景

  • 多个对象处理同一请求,具体哪个对象处理需要动态决定
  • 需要指定一组对象处理请求

3、优点

  • 将处理者和请求者进行解耦

4、缺点

  • 需要对处理者进行遍历,处理者过多会影响性能

5、类图

  • Handler:抽象处理者,声明请求处理的方法,并保持对下一个处理节点Handler的引用
  • ConcreteHandler:具体处理者,对请求进行处理,如果不能处理将请求转发给下一个节点

二、实例

1、抽象类Handler

/*** @Description 抽象处理者*/
public abstract class Handler {//下一个处理者private Handler mNextHandler;public Handler(){}/*** 传入下一个处理者* @param nextHandler*/public Handler(Handler nextHandler) {this.mNextHandler = nextHandler;}/*** 处理请求*/public final void handleRequest(Request request) {//请求者和处理者级别相同才进行处理if (getCurLevel() == request.getRequestLevel()) {handle(request);} else {//否则将请求交给下一个处理者if (mNextHandler != null) {mNextHandler.handleRequest(request);} else {System.out.print("无人处理");}}}/*** 获取处理者的级别* @return*/protected abstract int getCurLevel();/*** 当前处理者处理的逻辑* @param request*/protected abstract void handle(Request request);}复制代码

2、具体处理者

public class HandlerA extends Handler {public HandlerA(Handler nextHandler) {super(nextHandler);}@Overrideprotected int getCurLevel() {return 6;}@Overrideprotected void handle(Request request) {System.out.print("HandlerA 进行处理");}
}
复制代码
public class HandlerB extends Handler {public HandlerB() {}public HandlerB(Handler nextHandler) {super(nextHandler);}@Overrideprotected int getCurLevel() {return 10;}@Overrideprotected void handle(Request request) {System.out.print("HandlerB 进行处理");}
}
复制代码

3、抽象请求

public abstract class Request {/*** @return 请求的级别*/public abstract int getRequestLevel();
}复制代码

4、具体请求

public class RequestA extends Request {@Overridepublic int getRequestLevel() {return 10;}
}
复制代码

5、使用

public class HandlerTest {public static void main(String[] args) {RequestA request = new RequestA();//最后一个处理者Handler handlerB  = new HandlerB();//第一个处理者Handler handlerA = new HandlerA(handlerB);//最终传递到HandlerB处理handlerA.handleRequest(request);}
}
复制代码

三、OkHttp的Interceptor

纯的责任链模式是如果被处理者进行处理了,则请求传递结束。OkHttp的拦截器是不纯的责任链模式,在请求到达时,拦截器会做一些处理(比如添加参数等),然后传递给下一个拦截器进行处理。

1、请求拦截处理

在请求过程中,通过拦截器对请求进行处理

Response response = getResponseWithInterceptorChain();
复制代码
Response getResponseWithInterceptorChain() throws IOException {// 创建拦截器的listList<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));// 创建RealInterceptorChain,传入的index索引为0Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,originalRequest, this, eventListener, client.connectTimeoutMillis(),client.readTimeoutMillis(), client.writeTimeoutMillis());return chain.proceed(originalRequest);
}
复制代码

创建首个RealInterceptorChain对象,并传入拦截器的集合,通过proceed进行请求的处理。

2、请求处理

public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,RealConnection connection) throws IOException {......// 创建下一个RealInterceptorChain,将index+1(下一个拦截器索引)传入RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,writeTimeout);//获取当前的拦截器Interceptor interceptor = interceptors.get(index);//通过Interceptor的intercept进行处理Response response = interceptor.intercept(next);......return response;
}
复制代码
  • 创建下一个RealInterceptorChain对象,并将当前RealInterceptorChain中的变量当成参数传入,并将索引index+1传入。
  • 获取当前index位置上的拦截器,第一次创建时传入的index为0,表示获取第一个拦截器,后面会将index+1进入传入,用于获取下一个拦截器。
  • 在Interceptor的intercept中,将下一个RealInterceptorChain传入,内部会调用下一个RealInterceptorChain的proceed方法

3、Interceptor接口

public interface Interceptor {/*** 拦截Chain,并触发下一个拦截器的调用* @param chain 被处理的对象* @return* @throws IOException*/Response intercept(Chain chain) throws IOException;interface Chain {//返回请求Request request();//对请求进行处理Response proceed(Request request) throws IOException;......}
}
复制代码

4、ConnectInterceptor

public final class ConnectInterceptor implements Interceptor {public final OkHttpClient client;public ConnectInterceptor(OkHttpClient client) {this.client = client;}@Override public Response intercept(Chain chain) throws IOException {//下一个拦截链RealInterceptorChain realChain = (RealInterceptorChain) chain;//获取Request进行处理Request request = realChain.request();StreamAllocation streamAllocation = realChain.streamAllocation();// We need the network to satisfy this request. Possibly for validating a conditional GET.boolean doExtensiveHealthChecks = !request.method().equals("GET");HttpCodec httpCodec = streamAllocation.newStream(client, chain, doExtensiveHealthChecks);RealConnection connection = streamAllocation.connection();//会调用下一个拦截链的proceed进行处理return realChain.proceed(request, streamAllocation, httpCodec, connection);}
}
复制代码

ConnectInterceptor作为一个具体的处理者,接收到下一个RealInterceptorChain对象,通过RealInterceptorChain的proceed方法对请求进行处理。
整个链式调用的流程为:
首个Chain procced--首个Interceptor interceptor--
下一个Chain procced--下一个Interceptor interceptor--
下一个Chain procced--下一个Interceptor interceptor....

转载于:https://juejin.im/post/5c80d2a26fb9a04a01651c49

设计模式(四)OkHttp的责任链模式相关推荐

  1. 行为型设计模式(1)—— 责任链模式(Chain of Responsibility Pattern)

    文章目录 1.简介 2.使用场景 3.示例 4.变种 参考文献 1.简介 经常听身边的同事说其在项目中用到了责任链模式,今天就来学习一下什么是责任链模式. 责任链模式(Chain of Respons ...

  2. Android设计模式详解之责任链模式

    前言 责任链模式是行为型设计模式: 定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止. 使用场景: 多 ...

  3. 设计模式第七讲-责任链模式

    简介 责任链模式的定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系 将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止. 图例 责任链-根据事情大小来决 ...

  4. 设计模式(五)责任链模式

    一.什么是责任链模式?     责任链就是从一个起点发起请求,然后沿着任务链依次传递给每一个节点上的对象,直到有一个节点处理这个请求为止. 二.责任链模式实例实现? 1 public abstract ...

  5. Java设计模式(九)责任链模式 命令模式

    (十七)责任链模式 责任链模式的目的是通过给予多个对象处理请求的机会,已解除请求发送者与接受者之间的耦合关系.面对对象的开发力求对象之前保持松散耦合,确保对象各自的责任最小化.这种设计能够使得系统更加 ...

  6. 设计模式中的车轮战-责任链模式

    责任链模式在Android中的应用莫过于事件分发了,ViewGroup对事件分别给子View,从ViewTree的顶部至上而下地进行处理,直到事件被消化为止,这种方法在Android广播中也能看到 责 ...

  7. 设计模式(三)- 责任链模式

    职责链模式 文章目录 职责链模式 1.职责链模式 1.介绍 2.应用实例 代码 1.员工提交请求类:LeaveRequest 2. 抽象请假处理类:AbstractLeaveHandler 3.直接主 ...

  8. Java设计模式8,校验、审批流程改善神器,责任链模式

    目录 一.责任链模式 二.责任链模式的优缺点 1.优点 2.缺点 三.违背原则方案 1.Programmer实体类 2.数据校验 3.但是,似乎违反了一些设计原则 四.通过责任链模式重构代码 1.链路 ...

  9. 设计模式 - 责任链模式

    故事 前两天,没事又刷了一遍三国演义,看到关羽身在曹营心在汉,听说刘备在袁绍那里,然后就上演了"过五关,斩六将". 关羽过五关斩六将主要内容: 第一关,东岭关,斩守将孔秀. 东岭关 ...

最新文章

  1. 2018/8/27 A Modified PSO Algorithm with Exponential Decay Weight
  2. 方差分析(Analysis of Variance,ANOVA)是什么?方差分析的形式有哪些?
  3. 使用脚本规范化企业office程序注册名
  4. effective java英文版pdf_Java之Spring1:Spring简介、环境搭建、源码下载及导入MyEclipse...
  5. MCMC笔记Metropilis-Hastings算法(MH算法)
  6. 104_Power Query 数据库条件查询
  7. 夯实基础,彻底掌握js的核心技术(二):面向对象编程(Object Oriented Programming)
  8. E: Sub-process /usr/bin/dpkg returned an error code (1) Ubuntu安装apt-get命令报错
  9. 文本主题发现(一)-- 数据预处理
  10. Py之pandas:dataframe学习【转载】
  11. TCP长连接(KeepAlive)
  12. php5.3.3 xhprof,给CentOS6.3 + PHP5.3 安装PHP性能测试工具 XHProf-0.9.2
  13. 图片去水印的原理_去水印简单操作:图图去水印
  14. c语言 北京时间转换utc时间_UTC时间与北京时间相互转换
  15. WinCC Function TrendControl趋势图
  16. 13异步多线程(三)Parallel,线程安全
  17. 为何大数据在国内“雷声大雨点小”
  18. 现在能聊天的机器人都有哪些?
  19. 菜鸡哈屠教你合并果子
  20. 顶点着色器和片段着色器的区别

热门文章

  1. Java程序员必备的Intellij插件
  2. Android 使用Jsoup解析Html
  3. cmd.exe命令行方式执行matlab代码 【转】
  4. iphone 常用预编译代码
  5. C#路径/文件/目录/I/O常见操作汇总(一)
  6. 四门专业课,有点困难哈~
  7. 配置整合DWR3.0和Spring2.5使用annotation注解
  8. vts传感器采取船舶的_【火炬高企】船舶通讯导航设备专家新诺航科
  9. C语言经典例100-将学生成绩写入文件
  10. 【Windows 逆向】使用 Cheat Engine 工具进行指针扫描挖掘关键数据内存真实地址 ( 指针扫描 )