OkHttp源码中的原型模式之所以有必要单独拿出来讲,是因为OkHttp 3.x和4.x分别用Java语言和Kotlin语言写的,所以需要做一个对比分析。
本文所有3.x版本具体为3.14.2,所有4.x版本具体为4.12.0
OkHttpClient
3.x版本的OkHttpClient实现原型模式的源码如下:
public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
// ……代码省略……
}
4.x版本的OkHttpClient实现原型模式的源码如下:
open class OkHttpClient internal constructor(
builder: Builder
) : Cloneable, Call.Factory, WebSocket.Factory {
// ……代码省略……
}
可见无论3.x版本还是4.x版本,OkHttpClient实现原型模式都是直接调用super.clone进行浅拷贝。
Call
3.x版本的Call实现原型模式的源码如下:
public interface Call extends Cloneable {
// ……代码省略……
/**
* Create a new, identical call to this one which can be enqueued or executed even if this call
* has already been.
*/
Call clone();
}
Call的子类RealCall与原型模式有关的代码如下:
final class RealCall implements Call {
// ……代码省略……
private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
this.client = client;
this.originalRequest = originalRequest;
this.forWebSocket = forWebSocket;
}
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
// Safely publish the Call instance to the EventListener.
RealCall call = new RealCall(client, originalRequest, forWebSocket);
call.transmitter = new Transmitter(client, call);
return call;
}
@SuppressWarnings("CloneDoesntCallSuperClone") // We are a final type & this saves clearing state.
@Override public RealCall clone() {
return RealCall.newRealCall(client, originalRequest, forWebSocket);
}
// ……代码省略……
}
4.x版本的Call实现原型模式的源码如下:
interface Call : Cloneable {
// ……代码省略……
/**
* Create a new, identical call to this one which can be enqueued or executed even if this call
* has already been.
*/
public override fun clone(): Call
}
Call的子类RealCall与原型模式有关的代码如下:
class RealCall(
val client: OkHttpClient,
/** The application's original request unadulterated by redirects or auth headers. */
val originalRequest: Request,
val forWebSocket: Boolean
) : Call {
// ……代码省略……
@SuppressWarnings("CloneDoesntCallSuperClone") // We are a final type & this saves clearing state.
override fun clone() = RealCall(client, originalRequest, forWebSocket)
}
可见无论3.x还是4.x版本,RealCall实现原型模式都是直接new一个主要成员变量一致的新实例