首先看一下下面這個將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
切記第一反應就提供公有構造器,而不先考慮靜態工廠。