第一條:考慮用靜態工廠方法代替構造器

首先看一下下面這個將boolean 轉爲Boolean對象的方法:

public static Boolean valueof(boolean b){

    return b ? Boolean.TRUE : Boolean.FALSE;

}

利用靜態工廠方法提供了客戶端而不是構造器;

靜態工廠方法與構造器不同的優勢:

1、靜態工廠方法有自定義的名稱,產生的客戶端代碼更容易閱讀。

public class Services {
    public static Services newInstance(){
        return new Services();
    }
}

2、不需要再每次調用工廠方法都創建一個新的對象。

Boolean.valueof(boolean),就說明了這項技術,對實例對象進行重複利用,jdk源碼顯示:

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

public static final Boolean FALSE= new Boolean(false);

public static Boolean valueof(boolean b){

    return (b ? TRUE : FALSE);

}

以上的TRUE和FALSE實例對象,構建好實例之後,就緩存起來,重複利用,避免了重複創建對象。

3、靜態工廠方法可以返回原返回類型的任何子類型的對象

//Service interface

public interface Service {

}
//Service provider interface
public interface Provider {

    Service newService();
}

public class Services {

    private Services(){};

    private static final Map<String,Provider> providers=new ConcurrentHashMap<>();

    public static final String DEFAULT_PROVIDER_NAME="def";
    
    //provider registeration API
    public static void registerDefaultProvider(Provider p){
        registerProvider(DEFAULT_PROVIDER_NAME,p);
    }
    
    public static void registerProvider(String name,Provider p){
        providers.put(name,p);
    }
    // Service access API
    public static Service newInstance(){
        return newInstance(DEFAULT_PROVIDER_NAME);
    }
    public static Service newInstance(String name){
        Provider p=providers.get(name);
        if(p==null){
            throw  new IllegalArgumentException("No provider registered with name:"+name);
        }

        return p.newService();
    }
}

上述就是服務提供在框架,有三個重要的組件:服務接口、提供者註冊API,服務訪問API.

4、在創建參數化類型實例的時候,他們使代碼變得更加簡潔,最主要的是將多參數化的構造器簡化成了很少或者沒有參數的方法。更加簡潔,通過對靜態工廠方法命名,使得更加直觀。例如:

Map<String,List<Map<String,List<String>>>> map = new HashMap<String,List<Map<String,List<String>>>>()

隨着類型參數越來越長,越來越複雜,這一冗長的說明也很痛苦,但是有了靜態工廠方法,編譯器就可以替你找到類型參數.   

public static <K,V> HaahMap<K,V> newInstance(){
    retutn new HashMap<String,List<Map<String,List<String>>>>();
} 
在簡化成
Map<String,List<Map<String,List<String>>>> map = new HashMap<>();

之前,上述的靜態工廠方法就是一種好的選擇。

靜態工廠方法的缺點:

1、類如果不包含公有的或者受保護的構造器,就不能被子類化

2、他們與其他的靜態方法實際沒有任何區別。

靜態工廠方法的慣用名稱:

valueof 、  of   、getInstance、  newInstance、  getType 、 newType

切記第一反應就提供公有構造器,而不先考慮靜態工廠

發佈了25 篇原創文章 · 獲贊 6 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章