OkHttp设计模式剖析(二)责任链模式
2019-07-13 本文已影响0人
YongtaoHuang
上一篇 OkHttp设计模式剖析(一)建造者模式
下一篇 OkHttp设计模式剖析(三)策略模式
OKHTTP:
由大名鼎鼎的Square公司开发的网络通信库。
设计模式:
软件开发中问题的解决套路。
责任链模式简介
定义:使多个对象都有机会处理请求,从而降低收发之间的耦合。将这些对象连成一条责任链,沿着链传递该请求,直到被处理。
责任链模式将一个复杂的流程拆分给多个对象沿链逐一处理,或者给不同层级的对象沿链分级处理。
若源代码中有Chain这个词,大概率使用了责任链模式。
Interceptor(拦截器)类中的责任链模式
拦截器是一种强大的机制,可以监视、重写和重试调用。
整个拦截器链包括:所有应用拦截器,OkHttp核心,所有网络拦截器和网络调用者。
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