近來,我在學習如何在C#語言中使用設計模式中讀到一些資料,其中有關Singleton設計模式引起了我的注意。
學過設計模式的開發者都知道Singleton模式。我想簡要地解釋一下這個設計模式是為那些尚未學習過設計模式的朋友。Singleton設計模式是告訴您如何在你的應用程序創建一個唯一類示例的全局對象,也就是說,這個對象只能被實例化一次,這個對象同時提供一個訪問它的一個全局的訪問點。這種對象如應用程序中的窗口管理器或者是打印假脫機、數據庫連接池等。
現在讓我們先看一下設計模式一書中對Singleton模式的C++實現(為了方便比較,我把實現的代碼寫成內聯的方式):
class Singleton
{
public:
static Singleton* Instance()
{
if(_instance==0)
{
_instance=new Singleton;
}
return _instance;
}
protected:
Singleton();
Private:
Static Singleton* _instance;
};
Stington* Singleton::_instance=0;
這里我不想對上述的代碼作解釋,大家可以參閱本文后面提供的參考文獻。
為了更好的理解C#,我這里也出示一下Java中的Singleton模式實現代碼(不是有人認為C#是對Java的剽竊嗎J):
class Singleton
{
public Singleton Instance()
{
if(_instace==null)
{
synchronized (Class.forName("Singleton"))
{
if (_instance == null)
{
_instance = new Singleton();
}
}
}
return _instance;
}
protected Singleton() {}
private static Singleton _instance = null;
}
在上述的Java代碼中使用了雙重檢測機制,來避免多個線程的Singleton實例化問題。同樣,我也不想對上述的代碼做任何解釋。
首先,讓我們看一下C#中類似Java的實現:
class Singleton
{
public static Singleton Instance()
{
if(_instance==null)
{
lock (typeof(Singleton))
{
if(_instace==null)
{
_instance=new Singleton();
}
}
}
return _instance;
}
protected Singleton(){}
private static volatile Singleton _instance=null;
}
現在,是我們睜大眼睛的時候了,下面是利用.NET Framework平台優勢實現Singleton模式的代碼:
sealed class Singleton
{
private Singleton();
public static readonly Singleton Instance=new Singleton();
}
非常吃驚是不是,不僅代碼減少了許多,同時也解決了線程問題帶來的性能上損失。有避免了編譯器優化的問題。上述的代碼真的能正常工作嗎?如果能,那么它又是怎樣工作的呢?
注意到,Singleton類被聲明為sealed,以此保證它自己不會被繼承,其次沒有了Instance的方法,將原來_instance成員變量變成public readonly,並在聲明時被初始化。通過這些改變,我們確實得到了Singleton的模式,原因是在JIT的處理過程中,如果類中的static屬性被任何方法使用時,.NET Framework將對這個屬性進行初始化,於是在初始化Instance屬性的同時Singleton類實例得以創建和裝載。而私有的構造函數和readonly(只讀)保證了Singleton不會被再次實例化,這正是Singleton設計模式的意圖。
本文不是要討論設計模式,而只是想通過這個例子來說明一件事,那就是精通.NET Framework並將它靈活運用對實際應用開發的重要性。
參考文獻:
——設計模式:可復用面向對象軟件的基礎 [GOF]
——Design Pattern in C# [Jame W Cooper]