標籤:
第一條:考慮用靜態Factory 方法代替構造器
使用靜態Factory 方法的優勢:
- 靜態Factory 方法具有名稱,具有適當名稱的方法更易閱讀。
具有多個構造器的類使用者往往不知道該用哪個,可考慮提供多個合適命名的靜態Factory 方法。
不可變類可以預先建立好執行個體,或者將構件好的執行個體緩衝起來,從而避免重複建立對象。此方法類似於Flyweight模式。如果程式經常請求建立相同的對象,並且建立對象的代價很高,此項技術可以極大地提升效能。
在選擇返回對象的類時就有了更大的靈活性。比如:API可以提供對象,但是該對象實際的類可以被隱藏起來,使用者無需知道其具體類型。靜態Factory 方法返回的對象所屬的類,在編寫包含該靜態Factory 方法的類時可以不必存在。這種靈活的靜態Factory 方法構成了服務提供者架構的基礎。
簡單例子:
1 public interface Service {2 // service-specific methods go here3 }
public interface Provider { public Service newService();}
1 import java.util.Map; 2 import java.util.concurrent.ConcurrentHashMap; 3 4 /** 5 * Noninstantiable class for service registration and access 6 */ 7 public class Services { 8 private Services(){} //prevent instantiation 9 10 private static final Map<String, Provider> providers = new ConcurrentHashMap<>();11 private static final String DEFAULT_PROVIDER_NAME = "<def>";12 13 public static void registerDefaultProvider(Provider p) {14 registerProvider(DEFAULT_PROVIDER_NAME, p);15 }16 17 public static void registerProvider(String name, Provider p) {18 providers.put(name, p);19 }20 21 // Service access API22 public static Service newInstance() {23 return newInstance(DEFAULT_PROVIDER_NAME);24 }25 26 public static Service newInstance(String name) {27 Provider p = providers.get(name);28 29 if (null == p) {30 throw new IllegalArgumentException("No provider registered with name: " + name);31 }32 33 return p.newService();34 }35 36 }
在建立參數化型別執行個體時,使代碼變得簡潔
缺點:
主要缺點:類如果不含有公有的或者受保護的構造器,就不能被子類化。
第二個缺點在於,與其他靜態方法實際上沒有任何區別
沒有像構造器那樣在API文檔中明確標識出來,因此,對於一個提供了靜態方法而不是構造器的類來說,要想查明如何執行個體化一個類,是非常困難的。你可以在類或者介面注釋中關注靜態工廠,並遵守標準命名習慣,來彌補這一劣勢。
靜態Factory 方法的慣用名稱:
不太嚴格的講,該方法返回的執行個體與參數具有相同的值,這樣的靜態Factory 方法實際上是類型轉換方法。
valueOf的一種更簡潔的替代,在EnumSet中使用併流行起來
返回的執行個體是通過方法的參數來描述的,但是不能夠說與參數具有相同的值。
像getInstance一樣,但是newInstance能夠確保返回的每個執行個體都與所有其他執行個體不同
想getInstance一樣,但是在Factory 方法處於不同的類中的時候使用。Type表示Factory 方法返回的物件類型
像newInstance一樣,但是在Factory 方法處於不同的類中時候使用。
簡而言之,靜態Factory 方法和構造器都各有用處,需要理解各自的長處。靜態工廠通常更加合適,切忌第一反應就是提供公有的構造器,而不先考慮靜態Factory 方法。
[Effective Java]建立和銷毀對象