保證一個類別只有一個實例,並提供一個該實例的全域存取點。
——《設計模式》
單例模式的概念很簡單,以下以C#語言為例子,列出常見單例寫法的優缺點。
public sealed class Singleton { static Singleton instance = null; public void Show() { Console.WriteLine( "instance function"); } private Singleton() { } public static Singleton Instance { get { if (instance == null) { instance = new Singleton(); } return instance; } } }
評註:
優點:
由於實例是在Instance 屬性方法內部創建的,因此類別可以使用附加功能 直到物件要求產生一個實例才執行實例化;這種方法稱為「惰性實例化
」。惰性實例化避免了在應用程式啟動時實例化不必要的 singleton。
2、線程的安全
public sealed class Singleton { static Singleton instance = null; private static readonly object padlock = new object(); private Singleton() { } public static Singleton Instance { get { lock (padlock) { if (instance == null) { instance = new Singleton(); } } return instance; } } }
時刻加了鎖的那部分程式只有一個執行緒可以進入
物件實例由最先進入的那個執行緒創建
後來的執行緒在進入時(instence == null)為假,不會再去創建物件實例
增加了額外的開銷,損失了效能
3、雙重鎖定 public sealed class Singleton
{
static Singleton instance = null;
private static readonly object padlock = new object();
private Singleton()
{
}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (padlock)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
}
執行緒不是每次都加鎖
允許實例化延遲到第一次訪問物件時發生
4、靜態初始化
處理變數初始化
公共靜態屬性為存取實例提供了一個全域存取點
對實例化機制的控制權較少(.NET代為實作)
靜態初始化是在.NET 中實作Singleton 的首選方法靜態初始化是在.NET 中實現Singleton 的首選方法
靜態初始化是在.NET 中實現Singleton 的首選方法
靜態構造函數既沒有訪問修飾符,C#會自動把他們標記為private,之所以必須標記為private,
阻止開發人員
程式碼呼叫它,對它的呼叫總是由CLR負責的。
、延遲初始化
public sealed class Singleton
{
private static readonly Singleton instance = null;
static Singleton()
{
instance = new Singleton();
}
private Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
評註:
初始化工作由Nested類別的一個靜態成員來完成,這樣就實現了延遲初始化。
由於靜態函數的調用時機,是在類別被實例化或者靜態成員被調用的時候進行調用,
並且是由.net框架來調用靜態構造函數來初始化靜態構造函數來初始化靜態構造函數來初始化靜態構造函數來初始化靜態構造函數來初始化靜態構造函數來初始化靜態構造函數來初始化靜態構造函數來初始化靜態構造函數來初始化靜態構造函數來初始化靜態成員變量,
所以,如果按照寫法四來寫,再調用Hello方法的時候,就會實例化出來Singleton實例,這不是我們想看到的,
因為我們有可能只是想用Hello方法,而不是別的。
注意事項:
1、Singleton模式中的實例構造器可以設定為protected以允許子類別派生。
2、Singleton模式一般不要支援ICloneable接口,因為這可能會導致多個物件實例,與Singleton模式的初衷違背。
3、Singleton模式一般不要支援序列化,因為這也有可能導致多個物件實例,同樣與Singleton模式的初衷違背。
4、Singletom模式只考慮到了物件建立的管理,沒有考慮物件銷毀的管理。就支援垃圾回收的平台和物件的開銷來講,我們一般沒有必要對其銷毀進行特殊的管理。
總結:
1、Singleton模式是限製而不是改進類別的創建。
2、理解和擴展Singleton模式的核心是「如何控制使用者使用new對一個類別的建構器的任意呼叫」。
3、可以很簡單的修改一個Singleton,使它有少數幾個實例,這樣做是允許的而且是有意義的。
以上就是單例模式及常見寫法分析(設計模式01)的內容,更多相關內容請關注PHPcn中文(www.php.cn)!