說明:
讓一個類別只能有一個實例(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; } }
相關連結:設計模式整理列表
沒有留言:
張貼留言