文章作者:Tyan
博客:noahsnail.com
Chapter 2 Creating and Destroying Objects
THIS chapter concerns creating and destroying objects: when and how to create them, when and how to avoid creating them, how to ensure they are destroyed in a timely manner, and how to manage any cleanup actions that must precede their destruction.
這章是關(guān)于創(chuàng)建和銷毀對(duì)象的:什么時(shí)候怎樣創(chuàng)建它們,什么時(shí)候怎樣避免創(chuàng)建它們,怎樣確保它們被及時(shí)的銷毀,怎么管理任何清理操作,清理操作必須在對(duì)象銷毀之前。
Item 1: Consider static factory methods instead of constructors
Item 1: 考慮用靜態(tài)工廠方法代替構(gòu)造函數(shù)
The normal way for a class to allow a client to obtain an instance of itself is to provide a public constructor. There is another technique that should be a part of every programmer’s toolkit. A class can provide a public static factory method, which is simply a static method that returns an instance of the class. Here’s a simple example from Boolean (the boxed primitive class for the primitive type boolean). This method translates a boolean primitive value into a Boolean object reference:
一個(gè)類允許客戶獲得它本身的一個(gè)實(shí)例通常的方式是提供一個(gè)公有的構(gòu)造函數(shù)。還有另一種技術(shù)應(yīng)該成為每個(gè)程序員工具箱中的一部分。一個(gè)類可以提供一種公有的static factory method,static factory method是一種簡(jiǎn)單的靜態(tài)方法,它會(huì)返回一個(gè)類的實(shí)例。這有一個(gè)來(lái)自Boolean(基本類型boolean的封裝類)的簡(jiǎn)單例子。這個(gè)方法將一個(gè)布爾值轉(zhuǎn)成Boolean對(duì)象的引用:
public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}
Note that a static factory method is not the same as the Factory Method pattern from Design Patterns [Gamma95, p. 107]. The static factory method described in this item has no direct equivalent in Design Patterns.
注意靜態(tài)工廠方法與Design Patterns中的Factory Method是不同的。這個(gè)條目中描述的靜態(tài)工廠方法與設(shè)計(jì)模式中的工廠方法是不等價(jià)的。
A class can provide its clients with static factory methods instead of, or in addition to, constructors. Providing a static factory method instead of a public constructor has both advantages and disadvantages.
一個(gè)類可以為它的客戶提供靜態(tài)工廠方法來(lái)代替構(gòu)造函數(shù),或者除了構(gòu)造函數(shù)之外再提供一個(gè)靜態(tài)工廠方法。提供靜態(tài)工廠方法代替公有構(gòu)造函數(shù)既有優(yōu)點(diǎn)也有缺點(diǎn)。
One advantage of static factory methods is that, unlike constructors, they have names. If the parameters to a constructor do not, in and of themselves, describe the object being returned, a static factory with a well-chosen name is easier to use and the resulting client code easier to read. For example, the constructor BigInteger(int, int, Random), which returns a BigInteger that is probably prime, would have been better expressed as a static factory method named BigInteger.probablePrime. (This method was eventually added in the 1.4 release.)
與構(gòu)造函數(shù)相比,靜態(tài)工廠方法的第一個(gè)優(yōu)勢(shì)是它們有名字。如果構(gòu)造函數(shù)的參數(shù)本身不能描述返回的對(duì)象,具有合適名字的靜態(tài)工廠是更容易使用的,并且產(chǎn)生的客戶端代碼更易讀。例如,構(gòu)造函數(shù)BigInteger(int, int, Random)返回一個(gè)BigInteger,這個(gè)BigInteger可能是一個(gè)素?cái)?shù),使用名字為BigInteger.probablePrime的靜態(tài)工廠方法來(lái)表示會(huì)更好。(這個(gè)方法最終在1.4版本被引入。)
A class can have only a single constructor with a given signature. Programmers have been known to get around this restriction by providing two constructors whose parameter lists differ only in the order of their parameter types. This is a really bad idea. The user of such an API will never be able to remember which constructor is which and will end up calling the wrong one by mistake. People reading code that uses these constructors will not know what the code does without referring to the class documentation.
一個(gè)類只能有一個(gè)具有指定簽名的構(gòu)造函數(shù)。程序員知道怎樣規(guī)避這個(gè)限制:通過(guò)提供兩個(gè)構(gòu)造函數(shù),它們僅在參數(shù)列表類型的順序上有所不同。這真的是一個(gè)壞主意。使用這種API的用戶永遠(yuǎn)不能記住哪一個(gè)構(gòu)造函數(shù)是哪一個(gè),最后會(huì)無(wú)意中調(diào)用錯(cuò)誤的構(gòu)造函數(shù)。使用這些構(gòu)造函數(shù)的人在讀代碼時(shí)如果沒(méi)有類的參考文檔將不知道代碼要做什么。
Because they have names, static factory methods don’t share the restriction discussed in the previous paragraph. In cases where a class seems to require multiple constructors with the same signature, replace the constructors with static factory methods and carefully chosen names to highlight their differences.
因?yàn)殪o態(tài)工廠方法有名字,因此它們不會(huì)有上一段討論的那種限制。當(dāng)一個(gè)類似乎需要多個(gè)具有相同簽名的構(gòu)造函數(shù)時(shí),用靜態(tài)工廠方法代替構(gòu)造函數(shù),通過(guò)仔細(xì)選擇工廠方法的名字來(lái)突出它們的不同。
A second advantage of static factory methods is that, unlike constructors, they are not required to create a new object each time they’re invoked. This allows immutable classes (Item 15) to use preconstructed instances, or to cache instances as they’re constructed, and dispense them repeatedly to avoid creating unnecessary duplicate objects. The Boolean.valueOf(boolean) method illustrates this technique: it never creates an object. This technique is similar to the Flyweight pattern [Gamma95, p. 195]. It can greatly improve performance if equivalent objects are requested often, especially if they are expensive to create.
與構(gòu)造函數(shù)相比,靜態(tài)工廠方法的第二個(gè)優(yōu)勢(shì)是當(dāng)調(diào)用靜態(tài)工廠方法時(shí)不要求每次都創(chuàng)建一個(gè)新的對(duì)象。這允許不可變類(Item 15)使用預(yù)創(chuàng)建的實(shí)例,或緩存構(gòu)建好的實(shí)例,通過(guò)重復(fù)分發(fā)它們避免創(chuàng)建不必要的重復(fù)對(duì)象。Boolean.valueOf(boolean)方法闡明了這個(gè)技術(shù):它從未創(chuàng)建對(duì)象。這項(xiàng)技術(shù)與Flyweight模式類似[Gamma95, p. 195]。如果經(jīng)常請(qǐng)求相同的對(duì)象,它能極大的提升性能,尤其是在創(chuàng)建對(duì)象的代價(jià)較昂貴時(shí)。
The ability of static factory methods to return the same object from repeated invocations allows classes to maintain strict control over what instances exist at any time. Classes that do this are said to be instance-controlled. There are several reasons to write instance-controlled classes. Instance control allows a class to guarantee that it is a singleton (Item 3) or noninstantiable (Item 4). Also, it allows an immutable class (Item 15) to make the guarantee that no two equal instances exist: a.equals(b) if and only if a==b. If a class makes this guarantee, then its clients can use the == operator instead of the equals(Object) method, which may result in improved performance. Enum types (Item 30) provide this guarantee.
靜態(tài)工廠方法能從重復(fù)的調(diào)用中返回相同的對(duì)象,在任何時(shí)候都能使類嚴(yán)格控制存在的實(shí)例。這些類被稱為控制實(shí)例。編寫(xiě)控制實(shí)例類是有一些原因的。實(shí)例控制允許一個(gè)類保證它是一個(gè)單例(Item 3)或不可實(shí)例化的(Item 4)。它也允許一個(gè)不變的類(Item 15)保證不存在兩個(gè)相等的實(shí)例:a.equals(b)當(dāng)且僅當(dāng)a==b。如果一個(gè)類保證了這一點(diǎn),它的客戶端可以使用==操作符代替equals(Object)方法,這可能會(huì)導(dǎo)致性能的提升。Enum類型(Item 30)保證了這一點(diǎn)。
A third advantage of static factory methods is that, unlike constructors, they can return an object of any subtype of their return type. This gives you great flexibility in choosing the class of the returned object.
與構(gòu)造函數(shù)相比,靜態(tài)工廠方法的第三個(gè)優(yōu)勢(shì)是它們能返回它們的返回類型的任意子類型的對(duì)象。這樣在選擇返回對(duì)象的類時(shí)有了更大的靈活性。
One application of this flexibility is that an API can return objects without making their classes public. Hiding implementation classes in this fashion leads to a very compact API. This technique lends itself to interface-based frameworks (Item 18), where interfaces provide natural return types for static factory methods.Interfaces can’t have static methods, so by convention, static factory methods for an interface named Type are put in a noninstantiable class (Item 4) named Types.
靈活性的一個(gè)應(yīng)用是API能返回對(duì)象而不必使它們的類變成公有的。通過(guò)這種方式中隱藏實(shí)現(xiàn)類會(huì)有一個(gè)更簡(jiǎn)潔的API。這項(xiàng)技術(shù)適用于基于接口的框架(Item 18),接口為靜態(tài)工廠方法提供了自然的返回類型。接口不能有靜態(tài)方法,因此按慣例,命名為Type的接口的靜態(tài)工廠方法被放在一個(gè)命名為Types的不可實(shí)例化的類中(Item 4)。
For example, the Java Collections Framework has thirty-two convenience implementations of its collection interfaces, providing unmodifiable collections, synchronized collections, and the like. Nearly all of these implementations are exported via static factory methods in one noninstantiable class (java.util.Collections). The classes of the returned objects are all nonpublic.
例如,Java集合框架有三十二個(gè)集合接口的便利實(shí)現(xiàn),提供了不可修改的集合,同步集合等等。幾乎所有的這些實(shí)現(xiàn)都是通過(guò)靜態(tài)工廠方法導(dǎo)出在一個(gè)不可實(shí)例化的類中(java.util.Collections)。返回對(duì)象的類都是非公有的。
The Collections Framework API is much smaller than it would have been had it exported thirty-two separate public classes, one for each convenience implementation. It is not just the bulk of the API that is reduced, but the conceptual weight. The user knows that the returned object has precisely the API specified by its interface, so there is no need to read additional class documentation for the implementation classes. Furthermore, using such a static factory method requires the client to refer to the returned object by its interface rather than its implementation class, which is generally good practice (Item 52).
集合框架API比它導(dǎo)出的三十二個(gè)分開(kāi)的公有類更小,每一個(gè)便利實(shí)現(xiàn)對(duì)應(yīng)一個(gè)類。它不僅僅是API的數(shù)量在減少,還是概念上意義上的減少。用戶知道返回的對(duì)象含有接口指定的精確API,因此不需要閱讀額外的實(shí)現(xiàn)類的文檔。此外,使用這樣的靜態(tài)工廠方法需要客戶端使用接口引用返回的對(duì)象而不是使用它的實(shí)現(xiàn)類,這通常是最佳的實(shí)踐(Item 52)。
Not only can the class of an object returned by a public static factory method be nonpublic, but the class can vary from invocation to invocation depending on the values of the parameters to the static factory. Any class that is a subtype of the declared return type is permissible. The class of the returned object can also vary from release to release for enhanced software maintainability and performance.
不僅公有靜態(tài)工廠方法返回對(duì)象的類可以是非公有的,而且這個(gè)類還可以隨著調(diào)用靜態(tài)工廠時(shí)輸入的參數(shù)值的變化而變化。聲明的返回值類型的任何子類都是可以的。為了增強(qiáng)軟件的可維護(hù)性及性能,返回值對(duì)象的類也可以隨著發(fā)布版本的變化而變化。
The class java.util.EnumSet (Item 32), introduced in release 1.5, has no public constructors, only static factories. They return one of two implementations, depending on the size of the underlying enum type: if it has sixty-four or fewer elements, as most enum types do, the static factories return a RegularEnumSet instance, which is backed by a single long; if the enum type has sixty-five or more elements, the factories return a JumboEnumSet instance, backed by a long array.
在1.5版本中引入類java.util.EnumSet(Item 32),它沒(méi)有公有的構(gòu)造函數(shù),只有靜態(tài)工廠方法。根據(jù)枚舉類型的大小,靜態(tài)工廠方法返回兩個(gè)實(shí)現(xiàn)中的一個(gè),枚舉類型的分類:如果枚舉類型中有六十四個(gè)元素或更少,與大多數(shù)枚舉類型一樣,靜態(tài)工廠返回一個(gè)RegularEnumSet實(shí)例,由單個(gè)的long支持;如果枚舉類型中有六十五個(gè)元素或更多,靜態(tài)工廠方法返回一個(gè)JumboEnumSet實(shí)例,由long[]支持。
The existence of these two implementation classes is invisible to clients. If RegularEnumSet ceased to offer performance advantages for small enum types, it could be eliminated from a future release with no ill effects. Similarly, a future release could add a third or fourth implementation of EnumSet if it proved beneficial for performance. Clients neither know nor care about the class of the object they get back from the factory; they care only that it is some subclass of EnumSet.
現(xiàn)有的兩個(gè)實(shí)現(xiàn)類對(duì)于客戶端是不可見(jiàn)的。如果RegularEnumSet對(duì)于較少數(shù)量的枚舉類型沒(méi)有提供性能優(yōu)勢(shì),那么在將來(lái)的版本中將其移除不會(huì)任何影響。同樣地,如果新的EnumSet實(shí)現(xiàn)在性能上更有優(yōu)勢(shì),在將來(lái)的版本中添加EnumSet的第三或第四個(gè)實(shí)現(xiàn)也不會(huì)有任何影響??蛻舳瞬恢酪膊魂P(guān)心它們從工廠方法中得到的對(duì)象所屬的類;它們只關(guān)心它是EnumSet的某個(gè)子類。
The class of the object returned by a static factory method need not even exist at the time the class containing the method is written. Such flexible static factory methods form the basis of service provider frameworks, such as the Java Database Connectivity API (JDBC). A service provider framework is a system in which multiple service providers implement a service, and the system makes the implementations available to its clients, decoupling them from the implementations.
在編寫(xiě)靜態(tài)工廠方法所屬的類時(shí),靜態(tài)工廠方法返回的對(duì)象所屬的類可以不必存在。這種靈活的靜態(tài)工廠方法形成了服務(wù)提供者框架的基礎(chǔ),例如Java數(shù)據(jù)庫(kù)鏈接API(JDBC)。服務(wù)提供者框架是一個(gè)系統(tǒng):多個(gè)服務(wù)提供者實(shí)現(xiàn)一個(gè)服務(wù),系統(tǒng)為客戶端提供服務(wù)的多個(gè)實(shí)現(xiàn),使客戶端與服務(wù)實(shí)現(xiàn)解耦。
There are three essential components of a service provider framework: a service interface, which providers implement; a provider registration API, which the system uses to register implementations, giving clients access to them; and a service access API, which clients use to obtain an instance of the service. The service access API typically allows but does not require the client to specify some criteria for choosing a provider. In the absence of such a specification, the API returns an instance of a default implementation. The service access API is the “flexible static factory” that forms the basis of the service provider framework.
服務(wù)提供者框架有三個(gè)基本的組件:服務(wù)接口,提供者實(shí)現(xiàn);提供者注冊(cè)API,系統(tǒng)用來(lái)注冊(cè)實(shí)現(xiàn),使客戶端能訪問(wèn)它們;服務(wù)訪問(wèn)API,客戶端用來(lái)得到服務(wù)實(shí)例。服務(wù)訪問(wèn)API通常允許但不要求客戶端指定一些選擇提供者的規(guī)則。在沒(méi)有指定的情況下,API返回一個(gè)默認(rèn)的實(shí)現(xiàn)實(shí)例。服務(wù)訪問(wèn)API是"靈活的靜態(tài)工廠",其形成了服務(wù)提供者框架的基礎(chǔ)。
An optional fourth component of a service provider framework is a service provider interface, which providers implement to create instances of their service implementation. In the absence of a service provider interface, implementations are registered by class name and instantiated reflectively (Item 53). In the case of JDBC, Connection plays the part of the service interface, DriverManager.registerDriver is the provider registration API, DriverManager.getConnection is the service access API, and Driver is the service provider interface.
服務(wù)提供者框架的第四個(gè)可選組件是服務(wù)提供者接口,服務(wù)提供者通過(guò)實(shí)現(xiàn)這個(gè)接口來(lái)創(chuàng)建服務(wù)實(shí)現(xiàn)的實(shí)例。在沒(méi)有服務(wù)提供者接口的情況下,服務(wù)實(shí)現(xiàn)通過(guò)類名進(jìn)行注冊(cè),通過(guò)反射來(lái)進(jìn)行實(shí)例化(Item 53)。在JDBC的案例中,Connection是服務(wù)接口,DriverManager.registerDriver是提供者注冊(cè)API,DriverManager.getConnection服務(wù)訪問(wèn)API,Driver是服務(wù)提供者接口。
There are numerous variants of the service provider framework pattern. For example, the service access API can return a richer service interface than the one required of the provider, using the Adapter pattern [Gamma95, p. 139]. Here is a simple implementation with a service provider interface and a default provider:
服務(wù)提供者框架模式有許多變種。例如,服務(wù)訪問(wèn)API通過(guò)使用適配器模式[Gamma95, p. 139],能返回比提供者需要的更更豐富的服務(wù)接口。下面是服務(wù)提供者接口的一個(gè)簡(jiǎn)單實(shí)現(xiàn)和默認(rèn)的提供者:
// Service provider framework sketch
// Service interface
public interface Service {
... // Service-specific methods go here
}
// Service provider interface
public interface Provider {
Service newService();
}
// Noninstantiable class for service registration and access
public class Services {
private Services() { } // Prevents instantiation (Item 4)
// Maps service names to services
private static final Map<String, Provider> providers =
new ConcurrentHashMap<String, Provider>();
public static final String DEFAULT_PROVIDER_NAME = "<def>";
// Provider registration 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();
}
}
A fourth advantage of static factory methods is that they reduce the verbosity of creating parameterized type instances. Unfortunately, you must specify the type parameters when you invoke the constructor of a parameterized class even if they’re obvious from context. This typically requires you to provide the type parameters twice in quick succession:
靜態(tài)工廠方法的第四個(gè)優(yōu)勢(shì)是它們降低了創(chuàng)建參數(shù)化類型實(shí)例的冗長(zhǎng)性。遺憾的是,當(dāng)你調(diào)用參數(shù)化類的構(gòu)造函數(shù)時(shí),你必須指定類型參數(shù),即使它們?cè)谏舷挛闹惺欠浅C黠@的。這通常需要你緊接著提供兩次類型參數(shù):
Map<String, List<String>> m =
new HashMap<String, List<String>>();
This redundant specification quickly becomes painful as the length and complexity of the type parameters increase. With static factories, however, the compiler can figure out the type parameters for you. This is known as type inference. For example, suppose that HashMap provided this static factory:
隨著類型參數(shù)長(zhǎng)度和復(fù)雜性的增加,這個(gè)冗長(zhǎng)的說(shuō)明很快就讓人變得很痛苦。但是使用靜態(tài)工廠的話,編譯器可以為你找出類型參數(shù)。這被稱為類型推導(dǎo)。例如,假設(shè)HashMap由這個(gè)靜態(tài)工廠提供:
public static <K, V> HashMap<K, V> newInstance() {
return new HashMap<K, V>();
}
Then you could replace the wordy declaration above with this succinct alternative:
你可以將上面冗長(zhǎng)的聲明用下面簡(jiǎn)潔的形式去替換:
Map<String, List<String>> m = HashMap.newInstance();
Someday the language may perform this sort of type inference on constructor invocations as well as method invocations, but as of release 1.6, it does not.
某一天,Java語(yǔ)言可能在構(gòu)造函數(shù)調(diào)用上也有與方法調(diào)用類似的類型推導(dǎo),但到發(fā)行版本1.6為止,它一直沒(méi)有。
Unfortunately, the standard collection implementations such as HashMap do not have factory methods as of release 1.6, but you can put these methods in your own utility class. More importantly, you can provide such static factories in your own parameterized classes.
遺憾的是,但到發(fā)行版本1.6為止,標(biāo)準(zhǔn)集合實(shí)現(xiàn)例如HashMap沒(méi)有工廠方法,但你可以把這些方法放到你自己的工具類力。更重要的是,你可以在你自己的參數(shù)化類里提供這樣的靜態(tài)工廠。
The main disadvantage of providing only static factory methods is that classes without public or protected constructors cannot be subclassed. The same is true for nonpublic classes returned by public static factories. For example, it is impossible to subclass any of the convenience implementation classes in the Collections Framework. Arguably this can be a blessing in disguise, as it encourages programmers to use composition instead of inheritance (Item 16).
只提供靜態(tài)工廠方法的主要缺點(diǎn)是沒(méi)有公有或保護(hù)構(gòu)造函數(shù)的類不能進(jìn)行子類化。公有靜態(tài)工廠返回的非公有類同樣如此。例如,不可能子類化集合框架中的這些便利實(shí)現(xiàn)類??梢哉f(shuō)這是因禍得福,因?yàn)樗膭?lì)程序員使用組合來(lái)代替繼承(Item 16)。
A second disadvantage of static factory methods is that they are not readily distinguishable from other static methods. They do not stand out in API documentation in the way that constructors do, so it can be difficult to figure out how to instantiate a class that provides static factory methods instead of constructors. The Javadoc tool may someday draw attention to static factory methods. In the meantime, you can reduce this disadvantage by drawing attention to static factories in class or interface comments, and by adhering to common naming conventions. Here are some common names for static factory methods:
valueOf— Returns an instance that has, loosely speaking, the same value as its parameters. Such static factories are effectively type-conversion methods.of— A concise alternative tovalueOf, popularized byEnumSet(Item 32).getInstance— Returns an instance that is described by the parameters but cannot be said to have the same value. In the case of a singleton,getInstancetakes no parameters and returns the sole instance.newInstance— LikegetInstance, except thatnewInstanceguarantees that each instance returned is distinct from all others.getType— LikegetInstance, but used when the factory method is in a different class.Typeindicates the type of object returned by the factory method.newType— LikenewInstance, but used when the factory method is in a different class.Typeindicates the type of object returned by the factory method.
靜態(tài)工廠方法的第二個(gè)缺點(diǎn)是它們不能很容易的與其它靜態(tài)方法進(jìn)行區(qū)分。它們不能像構(gòu)造函數(shù)那樣在API文檔中明確標(biāo)識(shí)出來(lái),因此很難弄明白怎樣實(shí)例化一個(gè)提供靜態(tài)工廠方法代替構(gòu)造函數(shù)的類。Javadoc工具可能某一天會(huì)關(guān)注靜態(tài)工廠方法。同時(shí),你可以通過(guò)在類中或接口注釋中注意靜態(tài)工廠和遵循通用命名約定來(lái)減少這個(gè)劣勢(shì)。下面是靜態(tài)工廠方法的一些常用命名:
valueOf— 不嚴(yán)格地說(shuō),返回一個(gè)與它的參數(shù)值相同的一個(gè)實(shí)例。這種靜態(tài)工廠是有效的類型轉(zhuǎn)換方法。of—valueOf的一種簡(jiǎn)潔替代方法,通過(guò)EnumSet(Item 32)得到普及。getInstance— 返回一個(gè)通過(guò)參數(shù)描述的實(shí)例,但不能說(shuō)是相同的值。在單例情況下,getInstance沒(méi)有參數(shù)并且返回唯一的一個(gè)實(shí)例。newInstance— 除了newInstance保證每個(gè)返回的實(shí)例都是與其它的實(shí)例不同之外,其它的類似于getInstance,getType— 類似于getInstance,當(dāng)靜態(tài)工廠方法在不同的類中時(shí)使用。Type表示靜態(tài)工廠方法返回的對(duì)象類型。newType— 類似于newInstance,當(dāng)靜態(tài)工廠方法在不同的類中時(shí)使用。Type表示靜態(tài)工廠方法返回的對(duì)象類型。
In summary, static factory methods and public constructors both have their uses, and it pays to understand their relative merits. Often static factories are preferable, so avoid the reflex to provide public constructors without first considering static factories.
總之,靜態(tài)工廠方法和公有構(gòu)造函數(shù)都有它們的作用,理解它們的相對(duì)優(yōu)勢(shì)是值得的。靜態(tài)工廠經(jīng)常是更合適的,因此要避免習(xí)慣性的提供公有構(gòu)造函數(shù)而不首先考慮靜態(tài)工廠。
總結(jié):
1.靜態(tài)工廠的優(yōu)點(diǎn):
與構(gòu)造函數(shù)相比,靜態(tài)工廠方法的第一個(gè)優(yōu)勢(shì)是它們有名字。
與構(gòu)造函數(shù)相比,靜態(tài)工廠方法的第二個(gè)優(yōu)勢(shì)是當(dāng)調(diào)用靜態(tài)工廠方法時(shí)不要求每次都創(chuàng)建一個(gè)新的對(duì)象。
與構(gòu)造函數(shù)相比,靜態(tài)工廠方法的第三個(gè)優(yōu)勢(shì)是它們能返回它們的返回類型的任意子類型的對(duì)象。
靜態(tài)工廠方法的第四個(gè)優(yōu)勢(shì)是它們降低了創(chuàng)建參數(shù)化類型實(shí)例的冗長(zhǎng)性。
2.靜態(tài)工廠的缺點(diǎn):
只提供靜態(tài)工廠方法的主要缺點(diǎn)是沒(méi)有公有或保護(hù)構(gòu)造函數(shù)的類不能進(jìn)行子類化。
靜態(tài)工廠方法的第二個(gè)缺點(diǎn)是它們不能很容易的與其它靜態(tài)方法進(jìn)行區(qū)分。