[Patrón de diseño] Realización del patrón singleton en Unity

Prefacio

    El patrón de diseño es la mejor solución a algunos problemas generales que muchos desarrolladores han resumido en el proceso de desarrollo a largo plazo.
    El patrón singleton es uno de los más simples y de uso más común. Está dirigido a El problema es que la creación y destrucción frecuentes de objetos globales reutilizados desperdicia recursos del sistema. Por lo tanto, es adecuado para situaciones en las que desee controlar razonablemente el número de instancias para ahorrar recursos del sistema. Tiene las siguientes características:

1. Solo se puede crear una instancia de una clase singleton;

2. La instancia de la clase singleton se crea por sí misma y no a través del mundo exterior;

3. La clase singleton debe proporcionar esta instancia a objetos externos

La referencia anterior es del tutorial para novatos: modo singleton



Implementación

    El modo singleton en Unity se puede dividir aproximadamente en dos categorías :
heredar la clase MonoBehaviour y no heredar la clase MonoBehaviour .


Heredar la realización de la clase MonoBehaviour

    La forma en que las subclases de MonoBehaviour implementan el modo singleton es muy simple, simplemente cree una instancia estática y agregue la instancia = this. El código es el siguiente:

public class Singleton : MonoBehaviour
{
    
    
    public static Singleton instance;	//创建静态实例
	
	//防止外部进行额外的实例化将构造函数设为private
    private Singleton()
    {
    
     
        
    }

    void Awake()
    {
    
    
        instance = this;
    }

}

    La privatización del constructor puede evitar la creación de instancias adicionales desde el exterior:

Prevenir la instanciación



No hereda la implementación de la clase MonoBehaviour

    No implementación de la clase MonoBehaviour hereda es un poco más complicado, pero también se aplica a muchas implementaciones diferentes situaciones, como por ejemplo: un estilo de hambre hombre, tipo perezoso, las clases internas estáticas, perezosos, cerraduras dobles de verificación compatibles con el proceso, etc ......
    acaba aquí Hablemos de los primeros tres métodos de implementación enumerados anteriormente.

Hombre flojo

    La característica más importante del estilo lazy es que se inicializa solo la primera vez (carga diferida, que evita el desperdicio de recursos de memoria al extremo). Es simple de implementar, pero la desventaja es que no se da cuenta de la seguridad de múltiples subprocesos .

el código se muestra a continuación:

public class Singleton
{
    
    
    private static Singleton instance;
	
	//同样地,用私有化的构造函数来防止外界进行实例化
    Singleton(){
    
    }

    //提供给外界进行调用实例的方法,当然,也可以使用属性来进行代替
    public static Singleton GetSingleton() 
    {
    
    
        //如果进行调用时instance为null则进行初始化
        if (instance == null) 
        {
    
    
            instance = new Singleton();
        }
        return instance;
    }

}


Chino hambriento

    Dado que hay un hombre perezoso, es natural tener un hombre hambriento que es más diligente. Como su nombre indica, es diferente del hombre perezoso que se inicializa solo en la primera llamada.

Cuando se declara la instancia, se inicializa ,

el código se muestra a continuación:

public class Singleton
{
    
    
	//在进行实例声明的时候就完成初始化
    private static Singleton instance = new Singleton();
	
	//同样地,用私有化的构造函数限制外界进行实例化
    Singleton(){
    
    }

    //提供给外界进行调用实例的方法
    public static Singleton GetSingleton() 
    {
    
    
        return instance;
    }

}

    Mirándolo de esta manera, ¿crees que hay poca diferencia entre el estilo hambriento y el estilo perezoso, pero de hecho hay una gran diferencia entre ellos?

El hombre hambriento puede lograr la seguridad del hilo ,

Porque ya se ha inicializado cuando se declara, pero por lo tanto

Es fácil producir objetos basura en singletons que no se usan necesariamente y desperdiciar memoria


Clase interna estática

    El método de la clase interna estática es un poco más complicado de implementar que los dos anteriores, pero también tiene en cuenta la carga diferida y la seguridad de múltiples subprocesos.

el código se muestra a continuación:

public class Singleton
{
    
    
    Singleton(){
    
    }

    //提供给外界进行调用实例的方法
    public static Singleton GetSingleton() 
    {
    
    
        return InitSingleton.Instance;
    }

    //使用静态内部类完成初始化
    private static class InitSingleton 
    {
    
     
        public static Singleton Instance = new Singleton();
    }
}

    Entonces, la pregunta es nuevamente, ¿cómo logran ambas clases internas estáticas?

    Sabemos que la inicialización de los miembros estáticos se realiza cuando se carga la clase, y antes de llamar al método GetSingleton (), la clase InitSingleton no ha realizado ninguna llamada ,
    por lo que, naturalmente, el singleton Singleton no se ha inicializado .

La implementación segura de múltiples hilos del hombre hambriento y el mismo tipo de;



Aplicación eficiente

    La realización del patrón singleton está resuelta, pero ¿es demasiado problemático escribir esto cuando cada clase necesita implementar un singleton?

    Entonces, aquí, es el turno de la encapsulación y la herencia en el pensamiento orientado a objetos:
encapsular el patrón singleton en una clase base, y otras clases que necesitan implementar el patrón singleton solo necesitan heredar la clase de patrón singleton.

La clase base del patrón singleton es la siguiente (tome el chino hambriento como ejemplo):


public class Singleton<T> : MonoBehaviour where T : Component
{
    
    
    protected static GameObject SLT;
    protected static T instance;

    public static T Instance
    {
    
    
        get
        {
    
    
            if (instance == null)
            {
    
    
                if (SLT == null) 
                {
    
    
                	//负责进行调用的媒介
                    SLT = GameObject.Find("GlobalController").gameObject;
                }
                instance = SLT.GetComponent<T>();
            }
            return instance;
        }
    }

    protected Singleton(){
    
    }
}

Cuando la subclase hereda, solo necesita estar en la siguiente forma:
Herencia de subclase
pero no se puede llamar de esta manera . El script de la subclase debe estar montado en el objeto de medios que llama para poder acceder a él . Se puede usar un objeto vacío para montarlo específicamente. Y un script singleton que gestiona estos controles globales

Supongo que te gusta

Origin blog.csdn.net/Jourofant/article/details/108578615
Recomendado
Clasificación