單例模式 (Singleton Pattern)

單例模式是軟件工程中最著名的模式之一。從本質上講,單例是一個只允許創建自身的單個實例的類,通常可以簡單地訪問該實例。最常見的是,單例在創建實例時不允許指定任何參數 - 否則對實例的第二個請求但具有不同的參數可能會有問題!(如果對於具有相同參數的所有請求,應訪問相同的實例,則工廠模式更合適。)本文僅處理不需要參數的情況。通常,單例的要求是它們是懶惰地創建的 - 即在第一次需要之前不創建實例。

總結 Singleton 模式有兩個特點

  • 單一實例 (Single Instance)

  • 延遲建立實例 (Lazy Instantiation)

C# 實作

在C#中實現單例模式有各種不同的方法。從最常見的,不是執行緒安全的,以及完全延遲加載,安全,簡單且高性能的版本開始。

而有此共同特徵:

  • 單個構造函數,它是私有且無參數的。這可以防止其他類實例化它(這將違反模式)。(C#來說類別必須 sealed ,且 建構式為 private)

  • 一個靜態變量,用於保存對單個已創建實例的引用。(C# 來說需要一個 publicstatc 的 )

  • 公共靜態意味著獲取對單個創建實例的引用,必要時創建一個實例。(C# 來說類別需 publicstatic)

非執行緒安全 Singleton

這是個不好的案例,此方式不是執行緒安全,無法確保在多執行緒情況下是唯一的實例。

public sealed class NotThreadSafeSingleton
{
    private static NotThreadSafeSingleton _instance = null;

    private NotThreadSafeSingleton()
    {
    }

    public static NotThreadSafeSingleton Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new NotThreadSafeSingleton();
            }

            return _instance;
        }
    }
}

簡單執行緒安全 Singleton

使用 Lock 來確保執行緒安全。

使用 Double-checked Locking 確保執行緒安全

使用 Double-checked Locking 確保執行緒安全。

不使用 Lock, 確保執行緒安全 (非 Lazy)

此範例沒有使用 Lock, 而仍是執行緒安全的 Singleton,但不是 Lazy。

完整 Lazy 實例

此範例達成了延遲建立。

使用 .NET 4 的 Lazy

此方式使用後 .Net Framework 4 之後提供的 Lazy,如此可以簡單的達成 Singleton 要求的 唯一延遲建立

結語

除了第一個範例不建議之外,其餘的是可以依實際情況斟酌使用。

程式碼範例

Last updated