摘要:兩者都基于保持構(gòu)造函數(shù)私有并導(dǎo)出公共靜態(tài)成員以提供對(duì)唯一實(shí)例的訪問(wèn)。在一種方法中,該成員是字段私有構(gòu)造器只調(diào)用一次,用來(lái)初始化靜態(tài)變量。由于缺少或者屬性的構(gòu)造器,這就保證了的全局一致性一旦類被實(shí)例化,只會(huì)存在一個(gè)實(shí)例,不多也不少。
??Singleton指僅僅被實(shí)例化一次的類 [Gamma95]。Singleton通常代表無(wú)狀態(tài)的對(duì)象,例如函數(shù)(第24項(xiàng))或者本質(zhì)上唯一的系統(tǒng)組件。使類稱為Singleton會(huì)使它的客戶端測(cè)試變得十分困難,因?yàn)槌撬鼘?shí)現(xiàn)了作為其類型的接口,否則不可能將模擬實(shí)現(xiàn)替換為單例。
??實(shí)現(xiàn)單例的方法有兩種。 兩者都基于保持構(gòu)造函數(shù)私有并導(dǎo)出公共靜態(tài)成員以提供對(duì)唯一實(shí)例的訪問(wèn)。 在一種方法中,該成員是final字段:
// Singleton with public final field public class Elvis { public static final Elvis INSTANCE = new Elvis(); private Elvis() { ... } public void leaveTheBuilding() { ... } }
??私有構(gòu)造器只調(diào)用一次,用來(lái)初始化靜態(tài)變量Elvis.INSTANCE。由于缺少public或者protect屬性的構(gòu)造器,這就保證了Elvis的全局一致性:一旦Evlis類被實(shí)例化,只會(huì)存在一個(gè)Elvis實(shí)例,不多也不少。客戶端所做的任何事情都無(wú)法改變這一點(diǎn),但有一點(diǎn)需要注意:享有特權(quán)的客戶端可以借助AccessibleObject.setAccessible方法反射性地調(diào)用私有構(gòu)造函數(shù)(第65項(xiàng))。 如果你需要防御此攻擊,請(qǐng)修改構(gòu)造函數(shù)以使其在要求創(chuàng)建第二個(gè)實(shí)例時(shí)拋出異常。
??在實(shí)現(xiàn)Singleton的第二種方法中,公有的成員是個(gè)靜態(tài)工廠方法:
// Singleton with static factory public class Elvis { private static final Elvis INSTANCE = new Elvis(); private Elvis() { ... } public static Elvis getInstance() { return INSTANCE; } public void leaveTheBuilding() { ... } }
??對(duì)于靜態(tài)方法Elvis.getInstance的所有調(diào)用,都會(huì)返回同一個(gè)對(duì)象引用,所以,永遠(yuǎn)不會(huì)創(chuàng)建其他的Elvis實(shí)例(上述提醒依然適用)。
??公有域方法的主要好處在于,組成類的成員的聲明很清楚地聲明了這個(gè)類是一個(gè)Singleton:公有的靜態(tài)域是final的,所以該域總是包含同一個(gè)對(duì)象的引用。第二個(gè)好處就是它更加簡(jiǎn)單。
??工廠方法的優(yōu)勢(shì)之一在于,它提供了靈活性:在不改變其API的前提下,我們可以改變類是否應(yīng)該為Singleton的想法。工廠方法返回唯一實(shí)例,但是,它可以很容易被修改,比如改成每個(gè)調(diào)用該方法的線程返回一個(gè)唯一的實(shí)例。第二個(gè)優(yōu)點(diǎn)是,如果你的應(yīng)用需要,你可以編寫泛型單例工廠(第30項(xiàng))。使用靜態(tài)工廠的最后一個(gè)優(yōu)點(diǎn)是方法參考可以用作供應(yīng)商,例如Elvis::instance是供應(yīng)商
??為了使利用這其中一種方法實(shí)現(xiàn)的Singleton類編程可序列化的(第12章),僅僅在聲明中加上“implements Serializable”是不夠的。為了維護(hù)并保證Singleton,必須聲明所有實(shí)例域都是瞬時(shí)(transient)的,并提供一個(gè)readResolve方法(第89項(xiàng))。否則,每次反序列化時(shí),都會(huì)創(chuàng)建一個(gè)新的實(shí)例,在我們的示例中,會(huì)導(dǎo)致“假冒的Elvis”。為了防止這種情況,要在Elvis類中加入下面這個(gè)readResolve方法:
// readResolve method to preserve singleton property private Object readResolve() { // Return the one true Elvis and let the garbage collector // take care of the Elvis impersonator. return INSTANCE; }
??實(shí)現(xiàn)Singleton還有第三種方法。只需要編寫一個(gè)包含單個(gè)元素的枚舉類型:
// Enum singleton - the preferred approach public enum Elvis { INSTANCE; public void leaveTheBuilding() { ... } }
??這種方法類似于公共領(lǐng)域方法,但它更簡(jiǎn)潔,免費(fèi)提供序列化機(jī)制,并提供了對(duì)多個(gè)實(shí)例化的鐵定保證,即使面對(duì)復(fù)雜的序列化或反射攻擊。這種方法可能會(huì)有點(diǎn)不自然,但單元素枚舉類型通常是實(shí)現(xiàn)單例的最佳方法。請(qǐng)注意,如果你的單例必須擴(kuò)展Enum以外的超類,則不能使用此方法(盡管你可以聲明枚舉來(lái)實(shí)現(xiàn)接口)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/73904.html
摘要:一個(gè)類可以提供一個(gè)公共靜態(tài)工廠方法,它僅僅是一第項(xiàng)遇到多個(gè)構(gòu)造器參數(shù)時(shí)要考慮使用構(gòu)建器靜態(tài)工廠和構(gòu)造器有個(gè)共同的局限性他們都不能很好地?cái)U(kuò)展到大量的可選參數(shù)。 ??本章涉及創(chuàng)建和銷毀對(duì)象,包括何時(shí)以及如何創(chuàng)建它們,何時(shí)以及如何避免創(chuàng)建它們,如何確保它們被及時(shí)銷毀,以及如何管理在銷毀之前必須進(jìn)行的清理操作。 第1項(xiàng):用靜態(tài)工廠方法代替構(gòu)造器 ??類允許客戶端獲取實(shí)例的傳統(tǒng)方法是提供公共構(gòu)造...
摘要:推薦序前言致謝第一章引言第二章創(chuàng)建和銷毀對(duì)象第項(xiàng)用靜態(tài)工廠方法代替構(gòu)造器第項(xiàng)遇到多個(gè)構(gòu)造器參數(shù)時(shí)要考慮使用構(gòu)建器第項(xiàng)用私有構(gòu)造器或者枚舉類型強(qiáng)化屬性第項(xiàng)通過(guò)私有構(gòu)造器強(qiáng)化不可實(shí)例化的能力第項(xiàng)優(yōu)先考慮依賴注入來(lái)引用資源第項(xiàng)避免創(chuàng)建不必要的對(duì)象 推薦序 前言 致謝 第一章 引言 第二章 創(chuàng)建和銷毀對(duì)象 第1項(xiàng):用靜態(tài)工廠方法代替構(gòu)造器 第2項(xiàng):遇到多個(gè)構(gòu)造器參數(shù)時(shí)要考慮使用構(gòu)建器 第...
摘要:本章中的大部分內(nèi)容適用于構(gòu)造函數(shù)和方法。第項(xiàng)其他方法優(yōu)先于序列化第項(xiàng)謹(jǐn)慎地實(shí)現(xiàn)接口第項(xiàng)考慮使用自定義的序列化形式第項(xiàng)保護(hù)性地編寫方法第項(xiàng)對(duì)于實(shí)例控制,枚舉類型優(yōu)先于第項(xiàng)考慮用序列化代理代替序列化實(shí)例附錄與第版中項(xiàng)目的對(duì)應(yīng)關(guān)系參考文獻(xiàn) effective-java-third-edition 介紹 Effective Java 第三版全文翻譯,純屬個(gè)人業(yè)余翻譯,不合理的地方,望指正,感激...
摘要:第二章創(chuàng)建和銷毀對(duì)象何時(shí)以及如何創(chuàng)建對(duì)象,何時(shí)以及如何避免創(chuàng)建對(duì)象,如何確保他們能夠適時(shí)地銷毀,以及如何管理對(duì)象銷毀之前必須進(jìn)行的各種清理動(dòng)作。表示工廠方法所返回的對(duì)象類型。 第二章 創(chuàng)建和銷毀對(duì)象 何時(shí)以及如何創(chuàng)建對(duì)象,何時(shí)以及如何避免創(chuàng)建對(duì)象,如何確保他們能夠適時(shí)地銷毀,以及如何管理對(duì)象銷毀之前必須進(jìn)行的各種清理動(dòng)作。 1 考慮用靜態(tài)工廠方法代替構(gòu)造器 一般在某處獲取一個(gè)類的實(shí)例最...
閱讀 2304·2021-11-24 09:38
閱讀 2172·2021-11-22 14:44
閱讀 1162·2021-07-29 13:48
閱讀 2623·2019-08-29 13:20
閱讀 1123·2019-08-29 11:08
閱讀 2065·2019-08-26 10:58
閱讀 1270·2019-08-26 10:55
閱讀 3165·2019-08-26 10:39