前言
最近在看OkHttp
源碼,在整個OkHttp
中最重要也是最核心的就是攔截器了,簡單看攔截器似乎就是一個個實現(xiàn)Interceptor
接口的類啊犬,再分別在類中實現(xiàn)相應的邏輯,直到我看到下面的代碼
private 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 (!retryAndFollowUpInterceptor.isForWebSocket()) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(
retryAndFollowUpInterceptor.isForWebSocket()));
Interceptor.Chain chain = new RealInterceptorChain (
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
}
上述代碼中加入了很多個攔截器围详,這么多攔截器是怎么一個個實現(xiàn)的?
責任鏈模式
責任鏈模式將各個攔截器連接環(huán)環(huán)相扣祖屏,最終完成一次網(wǎng)絡請求助赞。
一個例子說明責任鏈應用場景
public class BrowRequest {
private int requestMoney;
public BrowRequest(int money) {
System.out.println("有新請求,需要借款" + money + "元");
requestMoney = money;
}
public int getRequestMoney() {
return requestMoney;
}
}
最核心的類赐劣, 處理類嫉拐,注意this.superior.approveRequest(browRequest);
簡單看似乎是自己調(diào)自己的方法,其實不然魁兼,這句代碼將處理交給了下一個對象setSuperior()
這個方法就是設置下一個傳遞對象婉徘,類似擊鼓傳花,將花遞給了下一個
abstract class AbstractClerk {
private AbstractClerk superior = null;
protected String type;
public abstract int getLimit();
public void setSuperior(AbstractClerk superior) {
this.superior = superior;
}
public void approveRequest(BrowRequest browRequest) {
if (getLimit() >= browRequest.getRequestMoney()) {
System.out.println(getType() + "同意借款請求");
} else {
if (this.superior != null) {
//傳遞給下一個使用
this.superior.approveRequest(browRequest);
} else {
System.out.println("沒有人能夠同意借款請求");
}
}
}
public String getType() {
return type;
}
}
接著就比較簡單了咐汞,定義我們的具體類盖呼,繼承處理類
public class Clerk extends AbstractClerk {
public Clerk() {
super.type = "職員";
}
@Override
public int getLimit() {
return 5000;
}
}
public class Leader extends AbstractClerk {
public Leader() {
super.type = "組長";
}
@Override
public int getLimit() {
return 20000;
}
}
public class Manager extends AbstractClerk {
public Manager() {
super.type = "經(jīng)理";
}
@Override
public int getLimit() {
return 100000;
}
}
最后在客戶端調(diào)用下就行了
public class Client {
public static void main(String[] args) {
AbstractClerk clerk = new Clerk();
AbstractClerk leader = new Leader();
AbstractClerk manager = new Manager();
clerk.setSuperior(leader);
leader.setSuperior(manager);
//有人借款10000元
clerk.approveRequest(new BrowRequest(10000));
//有人借款111000元
clerk.approveRequest(new BrowRequest(100000));
}
}
可以看到責任鏈跟現(xiàn)實生活中的擊鼓傳花游戲非常相似,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈化撕。
最核心的方法是處理類几晤, 一般處理類會包含一個指向下一處理類的成員變量,和一個處理請求的方法 植阴, 如果符合條件就自己處理蟹瘾,否則就傳遞給下一個處理圾浅。