建造者模式
首先我們先大致熟悉下通常的建造者模式
建造者模式(Builder Pattern)也叫生成器模式,其定義如下:將一個物件的構建與它的表示分離,使得同樣的構建程序可以創建不同的表示,
建造者模式的通用類圖如圖所示:

Product產品類 Builder抽象建造者
- 規范產品的組建,一般是由子類實作,
ConcreteBuilder
- 實作抽象類定義的所有方法,并且回傳一個組建好的物件,
Director導演類
產品類
public class Product {
public
public void doSomething(){
// 獨立業務邏輯
}
}
抽象建造者
public abstract class Builder {
// 設定產品的不同成分,已獲得不同的產品
public abstract Builder setPart();
// 建造產品
public abstract Product buildProduct();
}
public class ConcreteProduct extends Builder {
private Product product = new Product();
public Builder setPart(){
/*
* 產品類的內部邏輯
*/
...
return this;
}
// 創建一個產品
public Product build(){
return product;
}
}
導演類
public class Director {
private Builder builder = new ConcreteProduct();
// 構建不同的產品
public Product getAProduct(){
return build.setPart().build();
}
}
建造者模式的優點:
- 封裝性
使用建造者模式可以使客戶端不必知道產品內部組成的細節,
- 建造者獨立,容易擴展
- 便于控制細節風險
建造者模式的使用場景
- 相同的方法,不同的執行順序,產生不同的事件結果時,可以采用建造者模式
- 多個部件或零件,都可以裝配到一個物件中,但是產生的運行結果又不相同時,則可以使用該模式,
- 產品類非常復雜,或者產品類中的呼叫順序不同產生了不同的效能,這個時候使用建造者模式非常合適
- 在物件創建程序中會使用到系統中的一些其他物件,這些物件在產品物件的創建程序中不易得到時,也可以采用建造者模式封裝該物件的創建程序,
Retrofit中的構建者模式

OkHttpClient:這個是整個OkHttp的核心管理類,內部包含了請求調度器(Dispatcher),請求攔截器(interceptors),代理,讀寫超時時間等各種需要配置的物件,這里不就符合前面提到的建造者模式使用場景提到的那幾點嗎!
多個部件或零件,都可以裝配到一個物件中,但是產生的運行結果又不相同時,則可以使用該模式,
這些配置的物件就是構建OkhttpClient的多個部件/零件,配置不同,導致的運行結果也不同,就像connectTimeout配置的超時時間不同,導致請求結果允許超時時間也不同,
產品類非常復雜,或者產品類中的呼叫順序不同產生了不同的效能,這個時候使用建造者模式非常合適
在物件創建程序中會使用到系統中的一些其他物件,這些物件在產品物件的創建程序中不易得到時,也可以采用建造者模式封裝該物件的創建程序,
這里兩點可以合并起來看,OkhttpClient的很多配置物件,如CertificatePinner、protocols這些物件在OkhttpClient的創建程序中不易得到,且創建麻煩,我們應該用建造者模式封裝該物件的程序,而且用戶不應該知道如此多的創建細節,用戶只是要創建一個OkhttpClient物件,不然就違反了迪米特法則了,我們來看下OkhttpClient是具體是怎么實作建造者模式
open class OkHttpClient internal constructor(
builder: Builder
) : Cloneable, Call.Factory, WebSocket.Factory {
@get:JvmName("dispatcher") val dispatcher: Dispatcher = builder.dispatcher
@get:JvmName("connectionPool") val connectionPool: ConnectionPool = builder.connectionPool
/**
* Returns an immutable list of interceptors that observe the full span of each call: from before
* the connection is established (if any) until after the response source is selected (either the
* origin server, cache, or both).
*/
@get:JvmName("interceptors") val interceptors: List<Interceptor> =
builder.interceptors.toImmutableList()
/**
* Returns an immutable list of interceptors that observe a single network request and response.
* These interceptors must call [Interceptor.Chain.proceed] exactly once: it is an error for
* a network interceptor to short-circuit or repeat a network request.
*/
@get:JvmName("networkInterceptors") val networkInterceptors: List<Interceptor> =
builder.networkInterceptors.toImmutableList()
...
}
OKhttpClient建構式持有builder的依賴,然后其成員變數通過建構式獲取的builder物件,獲取其相應的配置物件,然后我們在看Builder類,
class Builder constructor() {
internal var dispatcher: Dispatcher = Dispatcher()
internal var connectionPool: ConnectionPool = ConnectionPool()
internal val interceptors: MutableList<Interceptor> = mutableListOf()
internal val networkInterceptors: MutableList<Interceptor> = mutableListOf()
internal var eventListenerFactory: EventListener.Factory = EventListener.NONE.asFactory()
internal var retryOnConnectionFailure = true
internal var authenticator: Authenticator = Authenticator.NONE
internal var followRedirects = true
....
internal var certificatePinner: CertificatePinner = CertificatePinner.DEFAULT
internal var certificateChainCleaner: CertificateChainCleaner? = null
internal var callTimeout = 0
internal var connectTimeout = 10_000
internal var readTimeout = 10_000
internal var writeTimeout = 10_000
internal var pingInterval = 0
internal var routeDatabase: RouteDatabase? = null
/**
* Sets the dispatcher used to set policy and execute asynchronous requests. Must not be null.
*/
fun dispatcher(dispatcher: Dispatcher) = apply {
this.dispatcher = dispatcher
}
/**
* Sets the connection pool used to recycle HTTP and HTTPS connections.
*
* If unset, a new connection pool will be used.
*/
fun connectionPool(connectionPool: ConnectionPool) = apply {
this.connectionPool = connectionPool
}
/**
* Returns a modifiable list of interceptors that observe the full span of each call: from
* before the connection is established (if any) until after the response source is selected
* (either the origin server, cache, or both).
*/
fun interceptors(): MutableList<Interceptor> = interceptors
fun sslSocketFactory(
sslSocketFactory: SSLSocketFactory,
trustManager: X509TrustManager
) = apply {
if (sslSocketFactory != this.sslSocketFactoryOrNull || trustManager != this.x509TrustManagerOrNull) {
this.routeDatabase = null
}
this.sslSocketFactoryOrNull = sslSocketFactory
this.certificateChainCleaner = CertificateChainCleaner.get(trustManager)
this.x509TrustManagerOrNull = trustManager
}
fun addInterceptor(interceptor: Interceptor) = apply {
interceptors += interceptor
}
...
fun build(): OkHttpClient = OkHttpClient(this)
}
}
這里的Builder類實際上是OkhttpClient的內部類,也就是產品類的內部類,它是一個具體建造者, Builder類默認的成員變數會對OkhttpClient的創建所需的物件進行一些默認創建初始化,并會提供一些配置方法,讓用戶也能靈活控制一些OkhttpClient的創建程序,像攔截器的添加,sslSocketFactory方法,他們回傳型別都為Builder,然后通過build()方法直接完成OkhttpClient的構建,
總結
建造者模式的優點:
- 封裝性
使用建造者模式可以使客戶端不必知道產品內部組成的細節,
- 建造者獨立,容易擴展
- 便于控制細節風險
建造者模式的使用場景
- 相同的方法,不同的執行順序,產生不同的事件結果時,可以采用建造者模式
- 多個部件或零件,都可以裝配到一個物件中,但是產生的運行結果又不相同時,則可以使用該模式,
- 產品類非常復雜,或者產品類中的呼叫順序不同產生了不同的效能,這個時候使用建造者模式非常合適
- 在物件創建程序中會使用到系統中的一些其他物件,這些物件在產品物件的創建程序中不易得到時,也可以采用建造者模式封裝該物件的創建程序
最后小編在這分享一份,我在學習提升時,從網上收集整理了一些 Android 開發相關的學習檔案、面試題、Android 核心筆記等等檔案,希望能幫助到大家學習提升,如有需要參考的可以直接去我 CodeChina地址:https://codechina.csdn.net/u012165769/Android-T3 訪問查閱,

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/294505.html
標籤:其他
上一篇:android通知詳解
