zoukankan      html  css  js  c++  java
  • 【Unity3D与23种设计模式】单例模式(Singleton)

    GoF中定义:

    “确认类只有一个对象,并提供一个全局的方法来获取这个对象”

    使用单例模式的前提

    它只能产生一个对象且不能够被继承

    单例模式的优点:

    提供方便获取唯一对象的方法

    可以限制对象的产生数量

    单例模式的缺点:

    容易造成设计思考不周和过度使用的问题

    违反了“开-闭原则”(OCP)

    using System.Collections;
    using UnityEngine;
    
    public class Test : MonoBehaviour
    {
        public static Test _instance;
    
        // Use this for initialization
        private void Start()
        {
            _instance = this;
        }
    
        // Update is called once per frame
        private void Update()
        {
        }
    }

    这两行代码就是一个最简单的静态变量

    可以看到,_instance是静态变量,因此可以在其他调用

    而_instance的类型又是类本身

    可以看做此类的一个实例

    这么一来,也就是可以在其他脚本中通过_instance调用Text脚本中的任何变量和方法

    在其他脚本中只需要使用此代码:

    Text._instance.XXX

    是不是很方便呢

    当然,当需要使用单例模式的脚本太多

    在每个脚本里都写这样的代码就有点违背代码简洁的初衷了

    所以呢,我们可以写一个单例模式的基类

    当某个脚本需要使用单例模式时,只需要继承这个脚本就可以了

    using System;  
    using System.Collections;  
    using System.Collections.Generic;  
       
       
    public class Singleton : MonoBehaviour  
    {  
        private static GameObject m_Container = null;  
        private static string m_Name = "Singleton";  
        private static Dictionary<string, object> m_SingletonMap = new Dictionary<string, object>();  
        private static bool m_IsDestroying = false;  
           
        public static bool IsDestroying  
        {  
            get { return m_IsDestroying; }  
        }  
           
        public static bool IsCreatedInstance(string Name)  
        {  
            if(m_Container == null)  
            {  
                return false;  
            }  
            if (m_SingletonMap!=null && m_SingletonMap.ContainsKey(Name))   
            {  
                return true;  
            }  
            return false;  
               
        }  
        public static object getInstance (string Name)  
        {  
            if(m_Container == null)  
            {  
                Debug.Log("Create Singleton.");  
                m_Container = new GameObject ();  
                m_Container.name = m_Name;      
                m_Container.AddComponent (typeof(Singleton));  
            }  
            if (!m_SingletonMap.ContainsKey(Name)) {  
                if(System.Type.GetType(Name) != null)  
                {  
                    m_SingletonMap.Add(Name, m_Container.AddComponent (System.Type.GetType(Name)));  
                }  
                else  
                {  
                    Debug.LogWarning("Singleton Type ERROR! (" + Name + ")");  
                }  
            }  
            return m_SingletonMap[Name];  
        }     
           
        public static void RemoveInstance(string Name)  
        {  
            if (m_Container != null && m_SingletonMap.ContainsKey(Name))  
            {  
                UnityEngine.Object.Destroy((UnityEngine.Object)(m_SingletonMap[Name]));  
                m_SingletonMap.Remove(Name);  
                  
                Debug.LogWarning("Singleton REMOVE! (" + Name + ")");  
            }  
        }  
       
        void Awake ()  
        {  
            Debug.Log("Awake Singleton.");  
            DontDestroyOnLoad (gameObject);  
        }  
           
        void Start()  
        {  
            Debug.Log("Start Singleton.");  
        }     
           
        void Update()  
        {  
        }  
           
        void OnApplicationQuit()  
        {  
            Debug.Log("Destroy Singleton");  
            if(m_Container != null)  
            {  
                GameObject.Destroy(m_Container);  
                m_Container = null;  
                m_IsDestroying = true;  
            }             
        }  
           
    }  

    例如,添加这个脚本后,我们要调用Test脚本的属性:

    Test text = Singleton.getInstance(“Text”) as Text;

    text.XXX

    这样就搞定了。。。

    最后:

    单例模式虽然好用,但是容易形成“单例癖”

    所以,应该咋仔细设计和特定的前提之下,适当地采用单例模式

  • 相关阅读:
    uva 10192 Vacation(最长公共子)
    SolrCloud应用简介
    2015第43周一solr相关概念
    2015第42周日
    2015第42周六Pgsql全文索引
    Java注解
    2015第42周四
    2015第42周三
    JS原型函数相关基础知识
    2015第42周一爬虫与反爬虫
  • 原文地址:https://www.cnblogs.com/fws94/p/6378585.html
Copyright © 2011-2022 走看看