第一條:考慮用靜態(tài)工廠方法代替構(gòu)造器
1. 簡(jiǎn)單介紹(個(gè)人理解)
這一條是告訴我們最好要這樣寫(xiě)一個(gè)類:
public class MyObject {
private String objectId;
private MyObject(String objectId) {//私有構(gòu)造器
this.objectId = objectId;
}
public static MyObject newInstance(String objectId){//靜態(tài)工廠方法
return new MyObject(objectId);
}
}
最好不要這樣:
public class MyObject {
private String objectId;
public MyObject(String objectId) {//共有構(gòu)造器
this.objectId = objectId;
}
}
2. 這樣做的原因(也就是好處):
1).靜態(tài)工廠方法我們可以自己定義名字,體現(xiàn)這個(gè)優(yōu)勢(shì)的地方在哪里?
答:在需要多個(gè)構(gòu)造器的時(shí)候,一堆構(gòu)造器雖然參數(shù)不同,但是名字相同,記住參數(shù)來(lái)識(shí)別不同的構(gòu)造器是不直觀的。
2).通過(guò)靜態(tài)工廠方法獲取實(shí)例可以不需要生成一個(gè)新對(duì)象,這個(gè)優(yōu)勢(shì)體現(xiàn)在哪里?
答:a. 你可以在類中創(chuàng)建一些static的默認(rèn)的實(shí)例,然后靜態(tài)工廠方法就可以直接返回這些實(shí)例,反復(fù)使用這些實(shí)例的時(shí)候相對(duì)于new出來(lái)要更加高效。
b. 你可以更容易的控制這些默認(rèn)的實(shí)例。
3).你可以返回一個(gè)當(dāng)前返回類型的子類對(duì)象,用簡(jiǎn)單的代碼解釋意思,看代碼:
public class MyObject{
public static MyObject getChildObject() { //靜態(tài)工廠方法
return MyChildObject.newInstance();
}
}
class MyChildObject extends MyObject{
public static MyChildObject newInstance() {
return new MyChildObject();
}
}
那么問(wèn)題來(lái)了,學(xué)挖。。。。額。。不對(duì),這個(gè)優(yōu)勢(shì)體現(xiàn)在什么地方呢?
答: 體現(xiàn)在面向接編程上,隱藏接口的實(shí)現(xiàn)類,使得接口的編寫(xiě)和調(diào)用更加簡(jiǎn)潔,并且可以直觀的看到有哪些實(shí)現(xiàn)類,并且可以直接的獲取到實(shí)現(xiàn)類的實(shí)例,當(dāng)然,接口里面是不能寫(xiě)靜態(tài)工廠方法的,所以我們需要做一些處理。代碼如下:
接口:
public interface Service {
void method();
}
通過(guò)一個(gè)Services提供各種接口的實(shí)現(xiàn):
public class Services {
private static final MyService myService = new MyService();
private static final AnotherService anotherService = new AnotherService();
private Services(){}
public static Service getMyService() {//構(gòu)造器
return myService;
}
public static Service getAnotherService(){//構(gòu)造器
return anotherService;
}
private static class MyService implements Service{
@Override
public void method() {
//do some things...
}
}
private static class AnotherService implements Service{
@Override
public void method() {
//do some things...
}
}
}
使用的時(shí)候:
Service mySevice = Services.getMyService();
Service anotherService = Services.getAnotherService();
3. 現(xiàn)在來(lái)說(shuō)說(shuō)缺點(diǎn):
缺點(diǎn)一:類如果不包含共有的或受保護(hù)的構(gòu)造器,就不能被子類化。
PS: 個(gè)人理解:類的構(gòu)造器如果是private類型的,它將不能被繼承,所以說(shuō)不能被子類化;
缺點(diǎn)二:想要查明一個(gè)類該如何被實(shí)例化十分困難。
-
總結(jié)
引用原文中的話:
簡(jiǎn)而言之,靜態(tài)工廠方法和共有構(gòu)造器都各有用處,我們需要理解他們各自的長(zhǎng)處。靜態(tài)工廠通常更加合適,因此切忌第一反應(yīng)就是提供共有的構(gòu)造器,而不先考慮靜態(tài)工廠。