建立者模式的特點及使用場景
《Effective Java》—— 建立與銷毀對象 一章中有寫道:當一個類中有大量的構造參數時,靜态方法和構造器已經不能滿足對象的執行個體化,那麼我們将考慮建構器。
建構器模式:
- 1、重疊構造器模式
- 2、javaBeans模式(自己常用的一種)
- 3、builder模式
說明:
- 重疊構造器模式:這種模式下,提供第一個隻有必要參數的構造器,第二個構造器有一個可選參數,第三個有兩個可選參數,以此類推,最後一個構造器包含所有可選參數。
- javaBeans模式:調用在各分無參構造器建立對象,然後調用setter方法來設定每個必要的參數,以及每個相關的可選參數。
- builder模式:builder像個構造器一樣,可以對其參數強加限制條件。build方法可以檢驗這些限制條件。将參數從builder拷貝到對象中之後,并在對象域而不是builder域中對它們進行檢驗,這一點很重要。如果違反了人格限制條件,build方法就應該抛出IllegalStateException。異常的詳細資訊應該顯示出違反哪個限制條件。
從上不難看出:
- 重疊構造器模式在參數很多的情況下,用戶端代碼會很難寫,并且難以閱讀。
- javaBeans模式因為構造過程分到了幾個調用中,在構造過程中javaBean可能處于不一緻的狀态,類無法僅僅通過校驗構造參數的* 有效性來保證一緻性。這樣程式員需要付出額外的努力來確定它的線程安全
- builder模式技能保證像重疊構造器模式那樣的安全性,也能保證像javaBeans模式那麼好的可讀性。
builder模式十分靈活,可以利用單個builder建構多個對象。builder的參數可以在建立對象期間進行調整,也可以随着不同的對象而改變。
代碼示例
class DefaultHttpClientFactory {
private static PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
private static RequestConfig defaultRequestConfig = RequestConfig.custom().build();
private static int mgrMaxTotal = DEFAULT_MAX_TOTAL; //全局最大連接配接數
private static int mgrDefaultMaxPerRoute = DEFAULT_MAX_PER_ROUTE; //每個主機最大連接配接數
private static int connReqTimeout = DEFAULT_CONN_REQ_TIMEOUT; //從連接配接池擷取連接配接逾時時間
private static int connTimout = DEFAULT_CONN_TIMEOUT; //發起連接配接逾時時間
private static int connSocketTimeout = DEFAULT_CONN_SOCKET_TIMEOUT; //連接配接套接字等待時間
public static class Builder {
private int mgrMaxTotal = DEFAULT_MAX_TOTAL; //全局最大連接配接數
private int mgrDefaultMaxPerRoute = DEFAULT_MAX_PER_ROUTE; //每個主機最大連接配接數
private int connReqTimeout = DEFAULT_CONN_REQ_TIMEOUT; //從連接配接池擷取連接配接逾時時間
private int connTimout = DEFAULT_CONN_TIMEOUT; //發起連接配接逾時時間
private int connSocketTimeout = DEFAULT_CONN_SOCKET_TIMEOUT; //連接配接套接字等待時間
Builder() {
}
public Builder maxTotal(int maxTotal) {
this.mgrMaxTotal = maxTotal;
return this;
}
public Builder maxPerRoute(int maxPerRoute) {
this.mgrDefaultMaxPerRoute = maxPerRoute;
return this;
}
public Builder connReqTimeout(int connReqTimeout) {
this.connReqTimeout = connReqTimeout;
return this;
}
public Builder connTimout(int connTimout) {
this.connTimout = connTimout;
return this;
}
public Builder connSocketTimeout(int connSocketTimeout) {
this.connSocketTimeout = connSocketTimeout;
return this;
}
public DefaultHttpClientFactory build() {
return new DefaultHttpClientFactory(this);
}
}
private DefaultHttpClientFactory(Builder builder) {
mgrMaxTotal = builder.mgrMaxTotal;
mgrDefaultMaxPerRoute = builder.mgrDefaultMaxPerRoute;
connReqTimeout = builder.connReqTimeout;
connTimout = builder.connTimout;
connSocketTimeout = builder.connSocketTimeout;
}
public static DefaultHttpClientFactory.Builder custom() {
return new DefaultHttpClientFactory.Builder();
}
public CloseableHttpClient getClient() {
cm.setMaxTotal(mgrMaxTotal); // 設定最大連接配接數
cm.setDefaultMaxPerRoute(mgrDefaultMaxPerRoute); // 設定每個路由最大連接配接數,每個獨立的host為1個路由
RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig)
.setConnectionRequestTimeout(connReqTimeout)//從連接配接池擷取連接配接逾時時間
.setConnectTimeout(connTimout)//發起連接配接逾時時間
.setSocketTimeout(connSocketTimeout)//連接配接套接字等待時間
.setRedirectsEnabled(false)
.build();
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
httpClientBuilder.setConnectionManager(cm);
httpClientBuilder.setDefaultRequestConfig(requestConfig);
httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(0, false)); // 去掉預設的3次重試
CloseableHttpClient httpClient = httpClientBuilder.build();
return httpClient;
}
}
歡迎關注
高廣超的簡書部落格與 收藏文章 !
頭條号:網際網路技術棧!
個人介紹:
** 高廣超** :多年一線網際網路研發與架構設計經驗,擅長設計與落地高可用、高性能網際網路架構。目前就職于美團網,負責核心業務研發工作。
本文首發在
轉載請注明!

image.png