說明:
讓一個類別只能有一個實例(Instance)的方法。
產生單一實例的方式:
懶漢方式(Lazy initialization):第一次使用時,才產生實例。
餓漢方式(Eager initialization):class 載入時就產生實例,不管後面會不會用到。
範例:
對同一個類別,分別取得 a、b 實例,而 a == b。
希望達成如下的效果
static void Main(string[] args)
{
// 產生第一個實例
Singleton a = Singleton.GetInstance();
Console.WriteLine("a.test = {0}", a.test); // a.test = 1
a.test = 10; // 將第一個實例的 test 值,改為 10
Console.WriteLine("a.test = {0}", a.test); // a.test = 10
// 產生第二個實例
Singleton b = Singleton.GetInstance();
Console.WriteLine("b.test = {0}", b.test); // b.test = 10
Console.WriteLine(b == a); // True, b 跟 a 是同一個實例
Console.Read();
}
執行結果: a.test = 1 a.test = 10 b.test = 10 True
實現重點在於,確保 class 回傳的實例,都是同一個,有以下兩種做法。
懶漢方式:第一次使用時,才產生實例
class Singleton
{
// 多執行緒,lock 使用
private static readonly object thisLock = new object();
// 將唯一實例設為 private static
private static Singleton instance;
public int test = 1;
// 設為 private,外界不能 new
private Singleton()
{
}
// 外界只能使用靜態方法取得實例
public static Singleton GetInstance()
{
// 先判斷目前有沒有實例,沒有的話才開始 lock,
// 此次的判斷,是避免在有實例的情況,也執行 lock ,影響效能
if (null == instance)
{
// 避免多執行緒可能會產生兩個以上的實例,所以 lock
lock (thisLock)
{
// lock 後,再判斷一次目前有無實例
// 此次的判斷,是避免多執行緒,同時通過前一次的 null == instance 判斷
if (null == instance)
{
instance = new Singleton();
}
}
}
return instance;
}
}
餓漢方式:class 載入時,即產生實例
public sealed class Singleton
{
// 設為 static,載入時,即 new 一個實例
private static readonly Singleton instance = new Singleton();
public int test = 1;
// 設為 private,外界不能 new
private Singleton()
{
}
// 使用靜態方法取得實例,因為載入時就 new 一個實例,所以不用考慮多執行緒的問題
public static Singleton GetInstance()
{
return instance;
}
}
相關連結:設計模式整理列表
沒有留言:
張貼留言