C#設計模式04-單例模式
昨天給大家介紹了原型模式,今天給大家介紹的是單例模式,也是最簡單的一種建立型模式。
在我們的軟體系統中,有時候保持一個類只有一個例項是非常重要的。比如說,作業系統中的工作管理員,只能有一個視窗,也就是說它在系統中只能有一個例項,否則就會彈出多個工作管理員視窗。再比如說,系統中的印表機,同一時間只能執行一個列印任務,如果有多個印表機例項,那麼同一時間可以列印多個任務,這會導致列印結果發生混亂。因此,軟體開發中,有時候保持一個類只有一個例項是非常重要的。
先看單例模式的定義:確保一個類只有一個例項,並提供一個全域性訪問點來訪問這個唯一例項。
那麼如何確保一個類只有一個例項並且可以被外部訪問呢?從定義上看有三點:一是一個類只能有一個例項,而是它必須自己建立這個例項(這樣可以防止外部對它例項化),三是它必須提供一個全域性的訪問點(靜態全域性變數)。
單例模式的角色非常簡單,只有一個單例類
那麼該如何實現單例模式呢?請看下面的程式碼
namespace 單例模式 { public class Singleton { //第二步:提供一個全域性訪問點,外部通過這個訪問點訪問例項 private static Singleton instance = null; //第一步:將建構函式宣告為Private,可以防止外部對該物件進行例項化 private Singleton() { } //第三步:單例類本身負責建立例項 public static Singleton GetInstance() { if (instance == null) instance = new Singleton(); return instance; } } }
namespace 單例模式
{
class Program
{
static void Main(string[] args)
{
Singleton s1 = Singleton.GetInstance();
Singleton s2 = Singleton.GetInstance();
if (s1 == s2)
{
Console.Write("s1和s2是同一個例項!");
}
else
{
Console.Write("s1和s2不是同一個例項!");
}
Console.ReadLine();
}
}
}
程式碼中單例模式的實現步驟已經寫得很清楚,這裡就不在作解釋了。下面看看執行結果
執行結果顯示s1和s2是同一個例項,說明外部物件拿到的是Singleton的同一個例項。
上面的實現方法是單例模式最簡單的實現方法。
接下來來介紹兩種不同實現方法的單例模式,餓漢式單例和懶漢式單例。
先來看看餓漢式單例類的程式碼。
namespace 單例模式
{
public class Singleton
{
private static Singleton instance = new Singleton();
private Singleton() { }
public static Singleton GetInstance()
{
return instance;
}
}
}
當類被載入的時候,靜態變數instance就會被初始化,然後建立單例類的例項。
然後我們來看看懶漢式單例模式的程式碼,懶漢式和餓漢式的建構函式都是私有的,不同的是懶漢式單例類不會在類載入時初始化單例類,而是在呼叫靜態工廠方法的時候例項化單例類。來看看下面的程式碼。
public class Singleton
{
private static Singleton instance = null;
private static readonly object lockObject = new object();
private Singleton() { }
public static Singleton GetInstance()
{
//第一次判斷
if (instance == null)
{
//加鎖,防止同一時刻多個執行緒同時訪問,導致例項化多個物件
lock (lockObject)
{
//第二次判斷
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
在程式碼中使用了Lock關鍵字對指定程式碼片段上鎖,防止同一時刻多個執行緒同時訪問單例類,最後導致系統的例項不是一個,而是多個。
程式碼中兩次判斷instance==null,是必不可少的。假如說兩個執行緒同時通過第一次判斷,第一個執行緒進入lock程式碼片段後,判斷instance還是為空,就例項化。如果第二個執行緒進來我們不判斷的話,它還會繼續例項化單例類。
下一篇文章將給大家介紹建立型模式中的最後一種—-建造者模式。