C#單例與繼承MonoBehaviour的單例

單例模式是我們最常用的一種設計模式。

主要優點:

1、提供了對唯一實例的受控訪問。

2、由於在系統內存中只存在一個對象,因此可以節約系統資源,對於一些需要頻繁創建和銷燬的對象單例模式無疑可以提高系統的性能。

3、允許可變數目的實例。

 

主要缺點:

1、由於單利模式中沒有抽象層,因此單例類的擴展有很大的困難。

2、單例類的職責過重,在一定程度上違背了“單一職責原則”。

3、濫用單例將帶來一些負面問題,如爲了節省資源將數據庫連接池對象設計爲的單例類,可能會導致共享連接池對象的程序過多而出現連接池溢出;如果實例化的對象長時間不被利用,系統會認爲是垃圾而被回收,這將導致對象狀態的丟失。


首先是普通的C#單例模式

public abstract class CSharpSingletion<T> where T : new() {  
  
    private static T instance;  
    public static T Instance  
    {  
        get  
        {  
            if (instance == null)  
            {  
                instance = new T();  
            }  
            return instance;  
        }  
    }  
  
}
using UnityEngine;  
using System.Collections;  
  
public class AudioSingletion : CSharpSingletion<AudioSingletion> {  
  
    public int i = 1;  
}  

這裏使用了範型類約束,當我們需要使用單例類時繼承這個單例類就可以,這樣就可以提高代碼的複用性。


接下來是Unity中繼承MonoBehaviour的單例類型,這裏做法和第一種類似,同樣使用繼承單例類的方法來實現統一管理。

using UnityEngine;
using System.Collections;

public class MonoSingletion<T> : MonoBehaviour where T :MonoBehaviour{

    private static string MonoSingletionName = "MonoSingletionRoot";
    private static GameObject MonoSingletionRoot;
    private static T instance;

    public static T Instance
    {
        get
        {
            if (MonoSingletionRoot==null)//如果是第一次調用單例類型就查找所有單例類的總結點
            {
                MonoSingletionRoot = GameObject.Find(MonoSingletionName);
                if (MonoSingletionRoot==null)//如果沒有找到則創建一個所有繼承MonoBehaviour單例類的節點
                {
                    MonoSingletionRoot = new GameObject();
                    MonoSingletionRoot.name = MonoSingletionName;
                    DontDestroyOnLoad(MonoSingletionRoot);//防止被銷燬
                }
            }
            if (instance == null)//爲空表示第一次獲取當前單例類
            {
                instance = MonoSingletionRoot.GetComponent<T>();
                if (instance == null)//如果當前要調用的單例類不存在則添加一個
                {
                    instance = MonoSingletionRoot.AddComponent<T>();
                }
            }
            return instance;
        }
    }

}


之後如果需要使用繼承了MonoBehaviour的單例類型只需要繼承MonoSingletion就可以


using UnityEngine;
using System.Collections;

public class MusicSingletion : MonoSingletion<MusicSingletion> {

    public void Show()
    {
        Debug.Log("Play Music");
    }
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	}
}

使用時只需要在其他地方調用 MusicSingletion.Instance.Show();就可以

發佈了33 篇原創文章 · 獲贊 9 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章