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进行构建。

相关推荐
小码过河.15 小时前
设计模式——建造者模式
单片机·设计模式·建造者模式
HIT_Weston18 小时前
104、【Ubuntu】【Hugo】搭建私人博客:搜索功能(AJAX请求)
ubuntu·ajax·okhttp
雨声不在18 小时前
okhttp的自定义dns解析
okhttp·dns
茶本无香18 小时前
设计模式之四:建造者模式(Builder Pattern)详解
java·设计模式·建造者模式
凛_Lin~~3 天前
安卓网络框架——OkHttp源码解析(基于3.14.x)
android·网络·okhttp
岁岁种桃花儿4 天前
XMLHttpRequest 从入门到实战:GET/POST 请求完整案例
ajax·okhttp
月月玩代码5 天前
OkHttp,Square出品的Java/Android HTTP客户端!
android·java·okhttp
m0_748254665 天前
AJAX 基础实例
前端·ajax·okhttp
胖虎17 天前
Android 文件下载实践:基于 OkHttp 的完整实现与思考
android·okhttp·下载文件·安卓下载·安卓中的下载
callJJ8 天前
Builder模式详解:从困惑到理解
java·建造者模式·智谱