筆記(NS)篇-單例模式(Singleton)

筆記(NS)篇-單例模式(Singleton)

簽名:你存在的價值,取決於能否解決相關的問題。

  • 單例模式的特點
  • 應用場景
  • 代碼演示
  • 其他參考寫法

單例模式的特點

1、在某種程度上,單例模式(Singleton)是限制而不是改進類的創建;
2、單例模式可以保證一個類有且只有一個實例;
3、提供一個訪問它的全局訪問點。

應用場景

1、使用Singleton模式有一個必要條件。在一個系統要求一個類只有一個實例時才應當使用單例模式。反過來,如果一個類可以有幾個實例共存,就不要使用單例模式;
2、不要使用單例模式存取全局變量。這違背了單例模式的用意,最好放到對應類的靜態成員中;
3、不要將數據庫連接做成單例,因爲一個系統可能會與數據庫有多個連接,並且在有連接池的情況下,應當儘可能地及時釋放連接。
singleton模式由於使用靜態成員存儲類實例,所以可能會造成資源無法及時釋放,帶來問題。

代碼演示

下面通過Singleton設計模式代碼演示了負載均衡實例對象。在負載均衡模型中,有多臺服務器提供服務,任務分配器隨機挑選一臺服務器提供服務,以確保任務均衡(實際情況比這個複雜的多),這裏,任務分配實例只能有一個,負責挑選服務器並分配任務。程序主要代碼如下:

using System;
using System.Collections;
using System.Threading;

namespace Singleton
{
    /// <summary>
    /// 負載均衡類
    /// </summary>
    class LoadBalancer
    {
        private static LoadBalancer loadBalancer;
        private ArrayList ArrayList_Server = new ArrayList();
        private Random random = new Random();
        protected LoadBalancer()                                            //構造函數
        {
            ArrayList_Server.Add("Server 1");
            ArrayList_Server.Add("Server 2");
            ArrayList_Server.Add("Server 3");
            ArrayList_Server.Add("Server 4");
        }
        public static LoadBalancer GetLoadBalancer()                        //創建實例的唯一入口
        {
            if (loadBalancer == null)                                       //靜態變量爲空
            {
                Mutex mutex = new Mutex();                                  //創建互斥體
                mutex.WaitOne();                                            //防止多用戶併發操作
                if (loadBalancer == null)
                    loadBalancer = new LoadBalancer();                      //創建類的實例
                mutex.Close();                                              //關閉互斥體
            }
            return loadBalancer;
        }
        public string Server
        {
            get
            {
                int r = random.Next(ArrayList_Server.Count);
                return ArrayList_Server[r].ToString();
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            LoadBalancer b1 = LoadBalancer.GetLoadBalancer();               //創建類的實例
            LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
            LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
            LoadBalancer b4 = LoadBalancer.GetLoadBalancer();
            if ((b1 == b2) && (b2 == b3) && (b3 == b4))                     //判斷實例是否相同
            {
                Console.WriteLine("同步運行相同的實例對象");
            }
            Console.WriteLine(b1.Server);
            Console.WriteLine(b2.Server);
            Console.WriteLine(b3.Server);
            Console.WriteLine(b4.Server);
            Console.ReadKey();
        }
    }
}

其他參考寫法

這裏要說的是,關於線程安全問題,除了使用Mutex進行防止併發操作外,還可以使用lock實現。

 public class MyCore
    {
        private static MyCore uniqueInstance;
        //定義一個線程同步,使外界不能創建該類實例
        private static readonly object locker = new object();
        private MyCore()
        {
        }
        public static MyCore GetInstance()
        {
            if (uniqueInstance == null)
            {
                lock (locker)
                {
                    if (uniqueInstance == null)
                    {
                        uniqueInstance = new MyCore();
                    }
                }
            }
            return uniqueInstance;
        }

    }

c#語言的特性決定了c#擁有實現Singleton模式的獨特方法。不詳細解釋,給出一個例子。

    public sealed class Singleton
    {
        Singleton() { }         //構造函數
        public static Singleton GetInstance()
        {
            return Nested.instance;
        }

        class Nested
        {
            static Nested() { }
            internal static readonly Singleton instance = new Singleton();
        }

    }

這樣雖然代碼很少,但解決了線程性能上的損失。工作原理是,Singleton類被聲明爲sealed,不會用於被繼承,將成員變量Instance聲明爲public readonly,並在聲明時被初始化。通過這些改變,確實得到了Singleton的設計模式,原因是在JIT的處理過程中如果類中的static屬性被任何方法使用時,.NET Framework將對這個屬性進行初始化,於是在初始化Instance屬性的同時Singleton類實例得以創建和裝載。而私有的構造函數和readonly關鍵字保證了singleton不會被再次實例化,這正是singleton設計模式的意圖。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章