設計模式-創建者模式總結

創建者模式的特點及使用場景

《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; }} 

個人介紹:

** 高廣超** :多年一線互聯網研發與架構設計經驗,擅長設計與落地高可用、高性能互聯網架構。

本文首發在 高廣超的簡書博客 (http://www.jianshu.com/p/6d4ca398c120)轉載請註明!


分享到:


相關文章: