[Effective Java]建立和銷燬對象

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

使用靜態工廠方法的優點:java

  • 靜態工廠方法具備名稱,具備適當名稱的方法更易閱讀。

具備多個構造器的類用戶每每不知道該用哪一個,可考慮提供多個合適命名的靜態工廠方法。緩存

  • 相比於構造器,沒必要再每次調用時都建立一個新對象

不可變類能夠預先建立好實例,或者將構件好的實例緩存起來,從而避免重複建立對象。此方法相似於Flyweight模式。若是程序常常請求建立相同的對象,而且建立對象的代價很高,此項技術能夠極大地提高性能。框架

  •  能夠返回原返回類型的任意子類型

在選擇返回對象的類時就有了更大的靈活性。好比:API能夠提供對象,可是該對象實際的類能夠被隱藏起來,用戶無需知道其具體類型。靜態工廠方法返回的對象所屬的類,在編寫包含該靜態工廠方法的類時能夠沒必要存在。這種靈活的靜態工廠方法構成了服務提供者框架的基礎。ide

簡單例子:性能

1 public interface Service {
2     // service-specific methods go here
3 }
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 API
22     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 }

 在建立參數化類型實例時,使代碼變得簡潔spa

缺點:code

主要缺點:類若是不含有公有的或者受保護的構造器,就不能被子類化。對象

第二個缺點在於,與其餘靜態方法實際上沒有任何區別blog

沒有像構造器那樣在API文檔中明確標識出來,所以,對於一個提供了靜態方法而不是構造器的類來講,要想查明如何實例化一個類,是很是困難的。你能夠在類或者接口註釋中關注靜態工廠,並遵照標準命名習慣,來彌補這一劣勢。接口

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

  • valueOf 

不太嚴格的講,該方法返回的實例與參數具備相同的值,這樣的靜態工廠方法其實是類型轉換方法。

  • of

valueOf的一種更簡潔的替代,在EnumSet中使用並流行起來

  • getInstance

返回的實例是經過方法的參數來描述的,可是不可以說與參數具備相同的值。

  • newInstance

像getInstance同樣,可是newInstance可以確保返回的每一個實例都與全部其餘實例不一樣

  • getType

想getInstance同樣,可是在工廠方法處於不一樣的類中的時候使用。Type表示工廠方法返回的對象類型

  • newType

像newInstance同樣,可是在工廠方法處於不一樣的類中時候使用。

 

簡而言之,靜態工廠方法和構造器都各有用處,須要理解各自的長處。靜態工廠一般更加合適,切忌第一反應就是提供公有的構造器,而不先考慮靜態工廠方法。

相關文章
相關標籤/搜索