1. 程式人生 > >用靜態工廠方法代替構造器、遇到多個構造器參數時要考慮用構建器

用靜態工廠方法代替構造器、遇到多個構造器參數時要考慮用構建器

泛型 不用 推斷 frame public 多參數 eof ram api

一、用靜態工廠方法代替構造器

類通過共有的構造方法可以提供很大的優點:
1、構造方法可一有不同的名字,我們可以通過名字區分構造什麽樣子的對象,而構造器名字相同,當參數列表的數目相同 順序不同時 很大的可能會用錯構造方法。

2、可以每次調用他們的時候都使用相同的對象(單例模式),可以對一個對象重復的利用,而每次調用構造方法都會新建一個對象。當程序需要創建相同的對象或者創建對象的代價很高時,使用靜態工廠是一個很好的選擇。

3、使用靜態工廠可以返回原返回類型的任意子類型。在靜態工程方法中可以根據不同的條件返回不用的對象。

服務提供者框架:多個服務提供者實現一個服務,系統為服務提供者的客戶端提供多個實現,並把他們從實現中解耦出來 減少服務提供者之間的關聯。

4、使用泛型 創建參數化類型實例的時候 可以讓代碼更簡潔。
編譯器可以通過靜態工廠來找到類型參數。

靜態工廠方法

以Java中自帶的Boolean類(基本類型boolean的包裝類)為例,它的靜態工廠方法為:

public static Boolean valueOf(boolean b) {
  return b ? Boolean.TRUE : Boolean.FALSE;
}

我們應該考慮用該方法替代構造器來獲得一個Boolean的實例。

//使用構造器
Boolean b1 = new Boolean(true);
//使用靜態工廠方法
Boolean b2 = Boolean.valueOf(true);

同樣是傳入一個true作為參數,兩種方法有什麽區別呢?

靜態工廠方法的優點

優點1:它們有名稱
假如我們想要提供多個具有相同簽名的構造器,這在Java中是做不到的,除非把參數列表的順序做些調整,但這會對用戶很不友好。因此可以使用靜態工廠方法,取不同的名字以表示不同的構造方式。

優點2:不必每次都創建新對象
適用於單例模式。

優點3:構成基於接口的框架
靜態工廠方法返回對象所屬的類可以是後來動態添加的。我們以服務提供者框架(Service Provider Framework)為例講解,該框架的代表是JDBC API。

優點4:創建泛型類實例的代碼更為簡潔
請看下面兩種創建泛型類實例的方式,後者比前者更為簡潔。

//使用構造器創建
Map<String, List<String>> m1 = new HashMap<String, List<String>>();
//使用靜態工廠方法創建
Map<String, List<String>> m2 = HashMap.newInstance();

前提是HashMap提供的靜態工廠方法newInstance定義如下

public static <K, V> HashMap<K, V> newInstance() {
  return new HashMap<K, V>();
}

這種情況下,編譯器可以通過返回值類型推斷K、V的具體類型。

靜態工廠的缺點

類如果不含有共有的或者受保護的構造方法,就不能被子類化。
當使用靜態工廠時,就是一個普通的static方法,在API文檔中,構造方法有單獨的區域,而靜態方法不會被分割出來。

我們一定要考慮使用靜態工廠!

二、遇到多個構造器參數時要考慮用構建器

當創建對象的時候需要大量的可選參數,那麽靜態工廠和構造器就不是好的選擇。可以采用的方式:

1、重疊構造器:提供第一個只有必要參數的構造器,第二個構造器包含一個可變參數 然後兩個可變參數一次類推 用this( )來調用 直到所有的可變參數都包含。
但是當有很多參數的時候,客戶端代碼會很難寫 並且難閱讀。

2、javaBeans模式 用setter 對屬性進行賦值,來設置必要參數和可變參數 但是當構造過程被分到了幾個調用中,在構造過程中javaBeans會出現不一致的狀態,即多線程的情況。

3、一種好的模式(Builder模式)
不直接生成想要的對象,而是讓客戶端利用所有必要的參數調用構造器(或者靜態工廠),得到一個builder對象。然後客戶端在builder對象上調用類似於setter的方法,來設置每個相關的可選參數。最後,客戶端調用無參的build方法來生成不可變的對象。
bulder可以是多個可變的參數。
對多個參數加約束條件時 可以用setter進行設置

構建器缺點:
1.構造器寫起來很復雜
2.創建對象開銷比較大
所以構建器模式只適用於需要傳入很多種情況參數的時候,比如大於4種參數的配合,才比較劃算。

用靜態工廠方法代替構造器、遇到多個構造器參數時要考慮用構建器