okhttp建造者模式详解

建造者模式的官方回答是

建造者模式(Builder Pattern) 是一种创建型设计模式,用于分步构建一个复杂对象,并将对象的构造过程与其表示分离,使得同样的构建过程可以创建不同的表示。

适用于:

  • 对象构造参数多(尤其是可选参数多);
  • 构造逻辑复杂;
  • 需要保证对象的不可变性(immutable)或线程安全

这个回答很模糊,我们来看看okhttp的源代码中定义从参数。

复制代码
final Dispatcher dispatcher;
final @Nullable Proxy proxy;
final List<Protocol> protocols;
final List<ConnectionSpec> connectionSpecs;
final List<Interceptor> interceptors;
final List<Interceptor> networkInterceptors;
final EventListener.Factory eventListenerFactory;
final ProxySelector proxySelector;
final CookieJar cookieJar;
final @Nullable Cache cache;
final @Nullable InternalCache internalCache;
final SocketFactory socketFactory;
final SSLSocketFactory sslSocketFactory;
final CertificateChainCleaner certificateChainCleaner;
final HostnameVerifier hostnameVerifier;
final CertificatePinner certificatePinner;
final Authenticator proxyAuthenticator;
final Authenticator authenticator;
final ConnectionPool connectionPool;
final Dns dns;
final boolean followSslRedirects;
final boolean followRedirects;
final boolean retryOnConnectionFailure;
final int callTimeout;
final int connectTimeout;
final int readTimeout;
final int writeTimeout;
final int pingInterval;

符合对象构造参数多(尤其是可选参数多)特点,通过final的修饰参数,来保证线程安全。符合第三个特点。

复制代码
public OkHttpClient() {
  this(new Builder());
}

OkHttpClient(Builder builder) {
  this.dispatcher = builder.dispatcher;
  this.proxy = builder.proxy;
  this.protocols = builder.protocols;
  this.connectionSpecs = builder.connectionSpecs;
  this.interceptors = Util.immutableList(builder.interceptors);
  this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
  this.eventListenerFactory = builder.eventListenerFactory;
  this.proxySelector = builder.proxySelector;
  this.cookieJar = builder.cookieJar;
  this.cache = builder.cache;
  this.internalCache = builder.internalCache;
  this.socketFactory = builder.socketFactory;

  boolean isTLS = false;
  for (ConnectionSpec spec : connectionSpecs) {
    isTLS = isTLS || spec.isTls();
  }

  if (builder.sslSocketFactory != null || !isTLS) {
    this.sslSocketFactory = builder.sslSocketFactory;
    this.certificateChainCleaner = builder.certificateChainCleaner;
  } else {
    X509TrustManager trustManager = Util.platformTrustManager();
    this.sslSocketFactory = newSslSocketFactory(trustManager);
    this.certificateChainCleaner = CertificateChainCleaner.get(trustManager);
  }

  if (sslSocketFactory != null) {
    Platform.get().configureSslSocketFactory(sslSocketFactory);
  }

  this.hostnameVerifier = builder.hostnameVerifier;
  this.certificatePinner = builder.certificatePinner.withCertificateChainCleaner(
      certificateChainCleaner);
  this.proxyAuthenticator = builder.proxyAuthenticator;
  this.authenticator = builder.authenticator;
  this.connectionPool = builder.connectionPool;
  this.dns = builder.dns;
  this.followSslRedirects = builder.followSslRedirects;
  this.followRedirects = builder.followRedirects;
  this.retryOnConnectionFailure = builder.retryOnConnectionFailure;
  this.callTimeout = builder.callTimeout;
  this.connectTimeout = builder.connectTimeout;
  this.readTimeout = builder.readTimeout;
  this.writeTimeout = builder.writeTimeout;
  this.pingInterval = builder.pingInterval;

  if (interceptors.contains(null)) {
    throw new IllegalStateException("Null interceptor: " + interceptors);
  }
  if (networkInterceptors.contains(null)) {
    throw new IllegalStateException("Null network interceptor: " + networkInterceptors);
  }
}

构造逻辑确实很复杂。

下面我们来看看是怎么构造

我们常见的构造方式是

复制代码
OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS)
        .addInterceptor(new LoggingInterceptor())
        .retryOnConnectionFailure(true)
        .build()

先看connectTimeout

复制代码
public Builder connectTimeout(long timeout, TimeUnit unit) {
  connectTimeout = checkDuration("timeout", timeout, unit);
  return this;
}

原来每次设置参数都会返回当前build对象的this指针,当前对象像个链条传个下一个设置参数的函数。

最后看build

复制代码
public OkHttpClient build() {
  return new OkHttpClient(this);
}

这里的this对象的类型是Builder,然后把Builder对象传递给OkHttpClient进行构建。

相关推荐
chilavert3181 天前
技术演进中的开发沉思-200 JavaScript:YUI 的AJAX 动态加载机制
javascript·ajax·okhttp
ZHE|张恒2 天前
设计模式(四)建造者模式 — 分步骤构建复杂对象,让创建过程可控可扩展
设计模式·建造者模式
永远的WEB小白2 天前
wordpress自定义订阅邮件发送
okhttp
明洞日记3 天前
【设计模式手册006】建造者模式 - 复杂对象的优雅构建之道
java·设计模式·建造者模式
曹绍华6 天前
okhttp详解
okhttp
老鼠只爱大米6 天前
Java设计模式之建造者模式(Builder)详解
java·设计模式·建造者模式·builder·23种设计模式
小毛驴8507 天前
软件建造者模式
建造者模式
天花板之恋8 天前
Android http网络请求的那些事儿
http·okhttp