• 【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

    这样就搞定了。。。

    最后:

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

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

  • 相关阅读:
    HTTP学习三:HTTPS
    JavaScript判断变量的类型
    用JS创建10个<a>标签,点击的时候弹出来对应的序号
    【工具】根据后端提供的swagger生成前端的axios请求配置文件/api
    JavaScript正则表达式-零宽断言
    JavaScript中数组去重、对象去重的方法
    收集的无版权图片网站(欢迎补充)
    css 清除浮动
    JavaScript+CSS+HTML 编写手风琴效果
    Mac定制终端:iTerm2 + zsh + powerline
  • 原文地址:https://www.cnblogs.com/fws94/p/6378585.html
Copyright © 2020-2023  润新知