Effective Java學(xué)習(xí)筆記 (一)考略使用靜態(tài)工廠方法代替構(gòu)造器

優(yōu)勢(shì):

1、 他們有名稱

通過(guò)名稱可以更清楚的知道這個(gè)方法的作用。
比如ImageLoader.loadIconImage(String url); 和 ImageLoader(String url,String type)、ImageLoader(String url)
用戶永遠(yuǎn)記不住參數(shù)類型順序上的有所不同,也記不住應(yīng)該用哪一個(gè)構(gòu)造器,所以會(huì)常常調(diào)用錯(cuò)誤構(gòu)造器。所以靜態(tài)工廠方法有名稱,可以不受這個(gè)的影響。

2、不必每次調(diào)用他們的時(shí)候都創(chuàng)建一個(gè)新的對(duì)象

這個(gè)可以使不可變類可以使用預(yù)先構(gòu)件好的實(shí)例。進(jìn)行重復(fù)使用。參考單例模式。

3、他們可以返回原返回類型的任何子類型的對(duì)象

這樣可以讓我們?cè)谶x擇對(duì)象的類的時(shí)候有了更大的靈活性。
這種靈活性的一種應(yīng)用是:API可以返回對(duì)象,同時(shí)又不會(huì)使對(duì)象的類變成共有的。以這樣的方式隱藏實(shí)現(xiàn)類會(huì)使API變得非常簡(jiǎn)單。

下面是一個(gè)簡(jiǎn)單的實(shí)現(xiàn),包含一個(gè)服務(wù)提供者接口和一個(gè)默認(rèn)提供者

//服務(wù)接口
public interface Service{
}
//服務(wù)提供者接口
public interface Provider{
//這個(gè)方法提供服務(wù)
Service newService();
}

public class Service{
//私有構(gòu)造方法
private Service(){}
//用來(lái)存放不同的服務(wù)提供者 根據(jù)名字區(qū)分
private static final Map<String,Provider> providers =
 new  ConcurrentHashMap<String,Providers>();
//默認(rèn)的服務(wù)提供者的名字
public static final String DEFAULT_PROVIDER_NAME = "<def>";
//默認(rèn)注冊(cè) 默認(rèn)名稱的服務(wù)提供者
public static void registerDefaultProvider(Provider p){
registerProvider(DEFAULT_PROVIDER_NAME,p);
}
//把自己創(chuàng)建名稱的服務(wù)提供者加入這個(gè)Map里
public static void registerDefaultProvider(String name,Provider p){
providers.put(name,p);
}
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();

}
}

這個(gè)是我們常見(jiàn)的服務(wù)提供者控件的簡(jiǎn)化版本。
我們可以看到通過(guò)我們不同的靜態(tài)工廠方法,使構(gòu)造方法私有,隱藏了實(shí)現(xiàn)類,只需要實(shí)現(xiàn)類實(shí)現(xiàn)這個(gè)接口就可以了,比如這個(gè)Provider,對(duì)于實(shí)現(xiàn)類我們是不可預(yù)料的,所以大大增加了靈活性。

4、再創(chuàng)建參數(shù)化類型實(shí)例的時(shí)候,他們使代碼變得更加簡(jiǎn)潔

比如這個(gè):

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

隨著類型參數(shù)的增加,會(huì)越來(lái)越長(zhǎng),越來(lái)越復(fù)雜,讓人很是痛苦。那我們用一下靜態(tài)工廠方法。

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

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

這樣是不是很爽啊。代替了繁瑣的聲明。

缺點(diǎn):

1、類如果不含共有的或者受保護(hù)的構(gòu)造器,就不能被子類化

對(duì)于共有的靜態(tài)工廠所返回的非共有類也是如此。
例如:要想將Collections FrameWork中的任何方便的實(shí)現(xiàn)類子類化,這是不可能的。但是也因禍得福,鼓勵(lì)程序員使用復(fù)合(composition),而不是繼承。

2、他們與其他的靜態(tài)方法沒(méi)有任何區(qū)別

小結(jié):

靜態(tài)工廠方法和公有構(gòu)造器都有各自的好處,通常下靜態(tài)工廠會(huì)更加合適。因此急切第一反應(yīng)就是提供公有構(gòu)造器,而要先考慮靜態(tài)工廠是否可以用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容