1.考慮用靜態工廠方法代替構造器

? ? ? 從類獲取實例,最常用是利用構造器,其次就是利用靜態工廠方法。例如下面方法將boolean基本類型值轉化為Boolean對象引用:

public static Boolean valueOf(boolean b){

? ? ? ? ?return b ? Boolean.True : Boolean.False;

}


使用靜態工廠方法的優勢:

(1)它們有名稱,可以通過名稱確定應該調用哪個靜態工廠方法,而構造器名稱都一樣,僅憑借參數不同不容易確定應該調用哪個構造方法。

(2)不必再每次調用它們的時候都創建一個對象。

例如上面的valueOf方法,返回的Boolean.True如下所示是事先創建好的對象。所以如果程序經常請求創建相同的對象并且創建對象的代價很高,那么有助于性能提高。

public static final Boolean TRUE= new Boolean(true);

靜態工廠方法,為重復的調用返回相同對象,有助于類控制某個時刻哪些實例應該存在,這叫做實例受控類(instance controlled)

實例受控類->Singleton類,不可實例化類,不可變類不會存在兩個相等的實例,即a==b才有a.equals(b)

(3)它們可以返回原返回類型的任何子類型的對象。

這樣API可以返回對象,同時又不會使對象的類變成共有的。例如Java Collections Framework集合有32個便利實現,幾乎所有實現都通過靜態工廠方法在一個不可實例化的類中導出,所有返回對象的類都是非公有的。

public static> EnumSetnoneOf(Class elementType) {

Enum[] universe =getUniverse(elementType);

if(universe ==null)

throw new ClassCastException(elementType +" not an enum");

if(universe.length<=64)

return new RegularEnumSet<>(elementType,universe);

else

return new JumboEnumSet<>(elementType,universe);

}

RegularEnumSet和JumboEnumSet都是非公有類,返回類型根據元素的個數發生變化。但這個類型必須是聲明類型的子類型。這兩個實現類對客戶端不可見,客戶端也不需在意,以后刪除這種實現或增加新的子類實現不會造成不良影響。

靜態工廠方法返回的對象所屬的類,在編寫包含該靜態工廠方法的類時可以不必存在。這是服務提供者框架的基礎。

服務提供者框架:多個服務提供者實現一個服務,系統為服務提供者的客戶端提供多個實現,并把他們從多個實現中解耦出來。框架主要有以下四個組成部分:

服務接口:提供者實現 JDBC Connection

提供者注冊API:系統注冊,客戶端訪問 DriverManager.registerDriver

服務訪問API:客戶端獲取服務 DriverManager.getConnection

服務提供者接口:服務提供者接口 Driver

(4)創建參數化類型實例時,它們使代碼變得更加簡潔(這個現在沒那么重要了)

Map<String,List<String>> m=new HashMap<String,List<String>>();

用靜態工廠:

public static<K,V> HashMap<K,V> newInstance(){

? ? ? ? return new HashMap<K,V>();

}

現在提供自動識別功能,所以這種方法就沒必要了。

Map<String,List<String>>m=new HashMap>();

靜態工廠方法主要缺點

(1)類如果不含共有的或受保護的構造器,就不能被子類化。

這從某種程度上鼓勵使用復合而不是繼承。

(2)它們與其他的靜態方法實際沒有任何區別,不過隨著Javadoc工具的完善,丑小鴨會變成白天鵝的。或者用以下靜態方法名稱來標示:

valueOf(of):實際上是一種類型轉化方法

getInstance:返回的實例通過方法的參數來描述。

newInstance:保證每個返回的實例與其他的都不同。

getType

newType

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容