上一篇 OkHttp設計模式剖析(一)建造者模式
下一篇 OkHttp設計模式剖析(三)策略模式
OKHTTP:
由大名鼎鼎的Square公司開發(fā)的網絡通信庫弹谁。
設計模式:
軟件開發(fā)中問題的解決套路呀枢。
責任鏈模式簡介
定義:使多個對象都有機會處理請求,從而降低收發(fā)之間的耦合纱扭。將這些對象連成一條責任鏈客蹋,沿著鏈傳遞該請求,直到被處理趾代。
責任鏈模式將一個復雜的流程拆分給多個對象沿鏈逐一處理冀瓦,或者給不同層級的對象沿鏈分級處理伴奥。
若源代碼中有Chain這個詞,大概率使用了責任鏈模式翼闽。
Interceptor(攔截器)類中的責任鏈模式
攔截器是一種強大的機制拾徙,可以監(jiān)視、重寫和重試調用肄程。
整個攔截器鏈包括:所有應用攔截器锣吼,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读恃,然后執(zhí)行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將事件派發(fā)到子View的過程歉摧。
互聯網開發(fā)流程可以看成責任鏈設計模式
不同級別的工程師都可以上手寫代碼艇肴,但是平時負責不同的業(yè)務。比如初級工程師負責基礎實現叁温,資深工程師負責架構搭建再悼,當然還有(代碼中省略),中級工程師負責核心優(yōu)化膝但,技術總監(jiān)負責技術管理等冲九。
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源碼設計模式解析與實戰(zhàn)》何紅輝,關愛民著
3灭贷、隔壁老李頭:http://www.reibang.com/p/82f74db14a18