责任链模式
建造者模式(Chain of Responsibility):有多个对象都有机会处理某个请求,从第一个请求开始,都会持有一个引用指向下一个请求(最后一个请求指向null
),从而形成一条链,沿着这条链传递请求,直到请求被处理或者传递到最后一个请求结束。
通用类图
责任链模式的通用类图如下所示:
优缺点
责任链模式的主要优点
- 责任链模式的显著优点是将请求和处理分离,两者各自注重实现自己的功能,符合类的单一职责。
- 功能修改和新增比较简单,新建链条替换原有即可
- 配合其他模式的时候扩展性和可编程性非常好,比如下文即将提到的
OkHttp
中的intercepter
的应用,就是用了模板方法模式+责任链模式。
责任链模式的主要缺点
- 责任链模式的显著缺点是性能问题,一个请求必须从头遍历整个链条,直到找到符合要求的处理类,在链条特别长,性能是个很大的问题。
OkHttp中的责任链模式
在OkHttp中OkHttpClient
中就有很明显的责任链模式的使用intercepter
,我们先看看OkHttp中责任链模式的大致类图。
可以明显看出和一般的责任链类图略有不同,属于变形的责任链,下面我们通过源码来看OkHttpClient
中Interceptor
中的责任链是怎么使用的。Interceptor
是网络请求的返回结果的拦截器,所以处理逻辑发生在处理http请求之后,http处理请求是发生在RealCall
中excute()
处理的,下面看下RealCall
中的源码,
@Override
public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
timeout.enter();
eventListener.callStart(this);
try {
client.dispatcher().executed(this);
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} catch (IOException e) {
e = timeoutExit(e);
eventListener.callFailed(this, e);
throw e;
} finally {
client.dispatcher().finished(this);
}
}
......
Response get