定義保證一個類僅有一個實例,並提供一個該實例的全局訪問點。 --《設計模式GoF》UML類圖使用場景當類只能有一個實例並且用戶可以從一個眾所周知的訪問點訪問它時。創建一個對象需要消耗過多的資源,比如IO和資料庫連接等。C#代碼實現1,初始版本namespace DesignPatternDemo.C... ...
定義
保證一個類僅有一個實例,並提供一個該實例的全局訪問點。 --《設計模式GoF》
UML類圖
使用場景
- 當類只能有一個實例並且用戶可以從一個眾所周知的訪問點訪問它時。
- 創建一個對象需要消耗過多的資源,比如IO和資料庫連接等。
C#代碼實現
1,初始版本
namespace DesignPatternDemo.ConsoleApp { /// <summary> /// 單例類 /// </summary> public class Singleton { private static Singleton _singleton; private Singleton() { } public static Singleton GetInstance() { if (_singleton== null) { _singleton = new Singleton(); } return _singleton; } } }
註意:此版本在多線程環境下不能保證線程安全!
2,雙檢鎖
namespace DesignPatternDemo.ConsoleApp { /// <summary> /// 單例類(雙檢鎖) /// </summary> public class SingletonV2 { private static SingletonV2 _singleton; private static readonly object lockObj = new object(); private SingletonV2() { } public static SingletonV2 GetInstance() { if (_singleton == null) { lock (lockObj) { if (_singleton == null) { _singleton = new SingletonV2(); } } } return _singleton; } } }
總結:雙檢鎖版本解決了多線程環境下線程安全的問題。
3,餓漢式版本
namespace DesignPatternDemo.ConsoleApp { /// <summary> /// 單例類(餓漢式版本) /// </summary> public class SingletonV3 { private static readonly SingletonV3 _singleton = new SingletonV3(); private SingletonV3() { } public static SingletonV3 GetInstance() { return _singleton; } } }
總結:這個版本的優點是實現簡單並且沒有加鎖執行效率高,缺點是類載入時就初始化,可能會浪費記憶體資源。
4,測試
namespace DesignPatternDemo.ConsoleApp { class Program { static void Main(string[] args) { SingletonV2 singleton1 = SingletonV2.GetInstance(); SingletonV2 singleton2 = SingletonV2.GetInstance(); if (singleton1 == singleton2) { Console.WriteLine("對象singleton1和對象singleton2是同一個對象!"); } Console.ReadKey(); } } }
運行結果: