whitefox 發表於 2023-5-29 13:27:26

[C#] 設計模式 Singleton 的六種方法

本帖最後由 whitefox 於 2023-5-29 13:29 編輯

在討論軟體工程的設計模式中,Singleton 單一實例化模式是最常見的方法之一
這提出六種常見的實作方式


[*]非線程安全
public sealed class Singleton1
{
    private static Singleton1 instance = null;
    private Singleton1() { }
    public static Singleton1 Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Singleton1();
            }
            return instance;
        }
    }
}
[*]簡單線程安全
public sealed class Singleton2
{
    private static Singleton2 instance = null;
    private static readonly object obj = new object();
    private Singleton2() { }
    public Singleton2 Instance
    {
        get
        {
            lock (obj)
            {
                if (instance == null)
                {
                    instance = new Singleton2();
                }
                return instance;
            }
        }
    }
}
[*]Double-Check-Locking 線程安全
public sealed class Singleton3
{
    private static Singleton3 instance = null;
    private static object obj = new object();
    private Singleton3() { }
    public static Singleton3 Instance
    {
        get
        {
            if (instance == null)
            {
                lock (obj)
                {
                    if (instance == null)
                    {
                        instance = new Singleton3();
                    }
                }
            }
            return instance;
        }
    }
}
[*]不加 Locking 線程安全/簡單 Lazy Type
public sealed class Singleton4
{
    private static readonly Singleton4 instance = new Singleton4();
    /// <summary>
    /// 顯式的靜態構造函數用來告訴 C# 編譯器在其内容實例化之前不要標註其類型
    /// </summary>
    static Singleton4() { }
    private Singleton4() { }
    public static Singleton4 Instance { get { return instance; } }
}
[*]完整 Lazy Type
public sealed class Singleton5
{
    private Singleton5() { }
    public static Singleton5 Instance { get { return Nested.instance; } }
    private class Nested
    {
        static Nested() { }
        internal static readonly Singleton5 instance = new Singleton5();
    }
}
[*].NET 4 的 Lazy Type
public sealed class Singleton6
{
    private static readonly Lazy<Singleton6> lazy =
           new Lazy<Singleton6>(()=> new Singleton6());
    public static Singleton6 Instance { get { return lazy.Value; } }
    private Singleton6() { }
}基本上方法1太過脆弱之外,其他實現方式應該在考量程式效能與執行時是否需要更早使用到類別中的靜態成員來抉擇實現方式
其他方法綜合比較下
方法2是比較容易編寫且加鎖執行也不會太慢
方法3與方法5的效能會受影響,但在構造函數不複雜下仍是建議的方法
方法4是效能與安全兼具的實作方法,但有比類別實例化更早應用的靜態成員,就不適合

個人經驗是使用方法3為主
頁: [1]
查看完整版本: [C#] 設計模式 Singleton 的六種方法