top
Loading...
Java模式設計之單例模式(四)


不完全的單例類

什么是不完全的單例類

估計有些讀者見過下面這樣的“不完全”的單例類。

代碼清單10:“不完全”單例類

package com.javapatterns.singleton.demos;
public class LazySingleton
{
private static LazySingleton
m_instance = null;
/**
* 公開的構造子,外界可以直接實例化
*/
public LazySingleton() { }
/**
* 靜態工廠方法
* @return 返還LazySingleton 類的惟一實例
*/
synchronized public static
LazySingleton getInstance()
{
if (m_instance == null)
{
m_instance = new LazySingleton();
}
return m_instance;
}
}

上面的代碼乍看起來是一個“懶漢”式單例類,仔細一看,發現有一個公開的構造子。由于外界可以使用構造子創建出任意多個此類的實例,這違背了單例類只能有一個(或有限個)實例的特性,因此這個類不是完全的單例類。這種情況有時會出現,比如javax.swing.TimerQueue 便是一例,關于這個類,請參見《Java與模式》一書中的“觀察者模式與Swing 定時器” 一章。

造成這種情況出現的原因有以下幾種可能:

(1) 初學者的錯誤。許多初學者沒有認識到單例類的構造子不能是公開的,因此犯下這個錯誤。有些初學Java 語言的學員甚至不知道一個Java 類的構造子可以不是公開的。在 這種情況下,設計師可能會通過自我約束,也就是說不去調用構造子的辦法,將這個不完全的單例類在使用中作為一個單例類使用。

在這種情況下,一個簡單的矯正辦法,就是將公開的構造子改為私有的構造子。

(2) 當初出于考慮不周,將一個類設計成為單例類,后來發現此類應當有多于一個的實例。為了彌補錯誤, 干脆將構造子改為公開的,以便在需要多于一個的實例時, 可以隨時調用構造子創建新的實例。要糾正這種情況較為困難,必須根據具體情況做出改進的決定。如果一個類在最初被設計成為單例類,但后來發現實際上此類應當有有限多個實例,這時候應當考慮是否將單例類改為多例類(Multiton)。

(3)設計師的Java 知識很好,而且也知道單例模式的正確使用方法,但是還是有意使用這種不完全的單例模式,因為他意在使用一種“改良”的單例模式。這時候, 除去共有的構造子不符合單例模式的要求之外,這個類必須是很好的單例模式。

默認實例模式

有些設計師將這種不完全的單例模式叫做“默認實例模式”(Default Instance Pattern)。在所謂的“ 默認實例模式”里面, 一個類提供靜態的方法,如同單例模式一樣, 同時又提供一個公開的構造子,如同普通的類一樣。

這樣做的惟一好處是,這種模式允許客戶端選擇如何將類實例化:創建新的自己獨有的實例,或者使用共享的實例。這樣一來,由于沒有任何的強制性措施,客戶端的選擇不一定是合理的選擇。其結果是設計師往往不會花費時間在如何提供最好的選擇上,而是不恰當地將這種選擇交給客戶端的程序員,這樣必然會導致不理想的設計和欠考慮的實現。

本文建議讀者不要這樣做。

作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗