Unity---游戲設計模式(3)之單例模式





1、單例類只能有一個實例。
2、單例類必須自己創建自己的唯一實例。
3、單例類必須給所有其他對象提供這一實例。

方法1

不推薦的方式1:只能用於單線程。
因為有可能會出現兩個線程同時判斷 _instance==null 然后都創建一個實例。這就不滿足單例模式了。

	//sealed修飾符,不可被繼承或重寫
    public sealed class Singleton1
    {
        private static Singleton1 _instance = null;
        public static Singleton1 Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new Singleton1();
                return _instance;
            }
        }
    }

方法2

不推薦的方式2:雖然能多線程但效率不高。
這樣當一個線程加鎖時,另一個線程只能等待。但是加鎖比較耗時,所以效率比較低。

    public sealed class Singleton2
    {
		//readonly動態變量修飾符
        private static readonly object locked = new object();

        private static Singleton2 _instance = null;
        public static Singleton2 Instance
        {
            get
            {
                lock (locked)
                {
                    if (_instance == null)
                        _instance = new Singleton2();
                }
                return _instance;
            }
        }
    }

方法3

還可以的方式3:前后兩次if語句判斷。
在加鎖前再判斷一次是否為空,這樣就只會在第一次創建的時候加鎖了。但是此方法比較麻煩,還有更好的方法。

    public sealed class Singleton3
    {
        private static readonly object locked = new object();

        private static Singleton3 _instance = null;
        public static Singleton3 Instance
        {
            get
            {
                //這樣不為空時,就不會再加鎖
                if (_instance == null)
                {
                    lock (locked)
                    {
                        if (_instance == null)
                            _instance = new Singleton3();
                    }
                }
                
                return _instance;
            }
        }
    }

方法4

推薦的方式4:靜態構造函數。
靜態構造函數的調用並不是由程序員決定的,而是在第一次用到Singleton4時就會被調用。所以有可能我們還沒有調用 Singleton4.Instance 的時候就已經被創建了,可能會降低內存使用效率。

    public sealed class Singleton4
    {
        //靜態變量在靜態構造函數被調用時初始化,所以只會初始化一次
        private static Singleton4 _instance = new Singleton4();
        public static Singleton4 Instance
        {
            get
            {
                return _instance;
            }
        }
    }

方法5

推薦的方式5:按需創建實例。
由Nested的靜態成員完成,實現按需初始化。

    public sealed class Singleton5
    {
        public static Singleton5 Instance
        {
            get
            {
                return Nested._instance;
            }
        }
            
        class Nested
        {
            static Nested()
            {

            }
			//internal修飾符。只有同一個程序集可訪問,可以跨類。
            internal static readonly Singleton5 _instance = new Singleton5();
        }
    }

2、單例模式優缺點

優點

  1. 只有一個實例,減少了內存消耗和系統性能開銷。

缺點

  1. 單例類的職責過重,在一定程度上違背了“單一職責原則”。
  2. 單例如果濫用會導致特殊一些問題。
  3. 單例類想擴展,只能修改源代碼。有點違反開閉原則。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM