1. 程式人生 > >設計模式篇:單例模式

設計模式篇:單例模式

在遊戲開發中,我們常常會在一個或多個類中引用到另一個類的方法。而這種情況下,我們通常是希望引用到的這個類是同一個類,因為我們要保證資料的同步性和一致性。

因此,單例模式就應運而生了。

單例模式,保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。

單例模式一般寫法

    public class TestSingleton
    {
        private static TestSingleton instance;

        /// <summary>
        /// 防止類外用new進行例項化此類,而造成多個類的後果
        /// </summary>
        private TestSingleton()
        {
        }

        /// <summary>
        /// 唯一的全域性訪問點
        /// </summary>
        public static TestSingleton Instance
        {
            get
            {
                //如果例項不存在,則new一個新例項,否則返回已有例項
                return instance ?? (instance = new TestSingleton());
            }
        }
    }

單例模式在繼承MonoBehaviour時的寫法

前面那個例子很簡單,可是當我們進行遊戲開發的時候,往往情況比這複雜的多,比如我們為了呼叫Unity的API,必須要繼承MonoBehaviour,而如果一個類繼承了MonoBehaviour,他就不能通過new來建立例項,

必須

才行,

所以,索性我們直接把要形成單例的類掛載到遊戲物體上,並編寫如下程式碼編寫單例

    public class TestSingleton:MonoBehaviour
    {
        private static TestSingleton instance;

        /// <summary>
        /// 防止類外用new進行例項化此類,而造成多個類的後果
        /// </summary>
        private TestSingleton()
        {
        }

        /// <summary>
        /// 唯一的全域性訪問點
        /// </summary>
        public static TestSingleton Instance
        {
            get
            {
                //
                if (instance == null)
                {
                    instance = FindObjectOfType<TestSingleton>();
                }

                return instance;
            }
        }
    }

使用單例模式的理由

單例模式因為Singleton類封裝他唯一例項,這樣他可以嚴格控制客戶怎樣訪問以及何時訪問它,簡單的說就是對唯一例項的訪問。

使用單例模式的場合

假如只是對某個類的欄位或成員變數進行訪問和更改,建議static,如果需要呼叫方法,那就做成單例。

思考:

單例模式是可以隨意使用的嗎?

並不是。

我們在開發中使用單例模式大多是想直接獲取物件,而省略層次複雜的引數傳遞。可是,當此單例所擔負的責任越來越大,專案就會原來越難以維護,其次,單例模式還違反了“開放——封閉”原則。因為,通過Instance獲取的是“實現類”而不是“介面類”,即得到的為實體類,當設計需求改變或增加時,它將無法被代替。只能更改原有實現類裡面的程式設計師,所以它不滿足“對修改封閉”要求。

於是,以單例模式為基礎,會有以下兩種實現方式

  • 子類向父類註冊實體物件,讓父類的Instance方法返回物件時,按條件查表返回對應的子類物件。
  • 每個子類都實現單例模式,再由父類的Instance去獲取這些子類