Patrones de diseño de uso común de Unity

Uno, modo singleton

En todo el ciclo de vida de nuestro juego, hay muchos objetos de principio a fin y solo uno. Esta instancia única solo debe generarse una vez y no es necesario destruirla hasta el final del juego.
El patrón singleton generalmente se aplica a clases de administrador, o algunos objetos que necesitan persistir.

Ventajas: es fácil de escribir y fácil de llamar.
Desventajas: dependencia fácil de formar, descuidando la colaboración con otros patrones de diseño.

Los dos modos singleton de Unity

  • Heredar el singleton de MonoBehaviour
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class GameManager : MonoBehaviour
{
    
    
    public static GameManager _instance;void Awake()
    {
    
    
        _instance = this;
    }
}
  • No hereda el singleton de MonoBehaviour
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class InstanceManager
{
    
    
    private static InstanceManager _instance;
    public static InstanceManager Instance
    {
    
    
        get
        {
    
    
            if (_instance == null)
            {
    
    
                _instance = new InstanceManager();
            }
            return _instance;
        }
    }}

En segundo lugar, el modelo de fábrica

Este tipo de patrón de diseño es un patrón de creación, que proporciona la mejor manera de crear objetos.

En el modelo de fábrica, no exponemos la lógica de creación al cliente cuando creamos un objeto, y usamos una interfaz común para apuntar al objeto recién creado.

Ejemplos de aplicación: 1. Si necesita un automóvil, puede recoger la mercancía directamente de la fábrica, independientemente de cómo esté hecho el automóvil y de la implementación específica en el automóvil.
2. Hibernate solo necesita cambiar el dialecto y el controlador para cambiar la base de datos.

Ventajas: 1. Una persona que llama quiere crear un objeto, siempre que sepa su nombre.
2. Alta escalabilidad: si desea agregar un producto, solo necesita extender una clase de fábrica.
3. Proteja la implementación específica del producto, y la persona que llama solo se preocupa por la interfaz del producto.

Desventajas: cada vez que se agrega un producto, se debe agregar una clase concreta y una fábrica de implementación de objetos, lo que duplica el número de clases en el sistema, lo que aumenta la complejidad del sistema hasta cierto punto y también aumenta el número de clases específicas. clases en el sistema. Esto no es bueno.

Tomemos el automóvil de producción como ejemplo. Hay tres tipos de Geely, Hongqi y Volkswagen. Estos tres son todos automóviles. Luego, primero escribimos una interfaz de automóvil. El automóvil también puede usar la clase base. El rendimiento es el mismo. Los tres tipos de personas tienen métodos de producción.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface Car
{
    
    
    void Production();
}

public class VW :Car
{
    
    
    public void Production()
    {
    
    
        Debug.Log("生产一辆大众");
    }
}

public class GeelyAutomobile : Car
{
    
    
    public void Production()
    {
    
    
        Debug.Log("生产一辆吉利");
    }
}

public class RedFlagCar : Car
{
    
    
    public void Production()
    {
    
    
        Debug.Log("生产一辆红旗");
    }
}

Se han creado las tres clases de automóviles. Para comenzar la producción de fábrica, cree una Clientela de clase de fábrica, ingrese la cadena / Int / tipo acordado, y puede comenzar la producción. Aquí usamos un método de producción estático para continuar. Producción, por lo que es simple El modelo de fábrica también se denomina modelo de producción estático.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Clientele
{
    
    

    public static Car Clienteles(string carname)
    {
    
    
        switch (carname)
        {
    
    
            case "VW":
                return new VW();

            case "GeelyAutomobile":
                return new GeelyAutomobile();

            case "RedFlagCar":
                return new RedFlagCar();

            default:
                break;
        }
        return null;
    }
}

Ahora tenemos que hacer una prueba, vamos a producir y procesar el auto, solo necesitamos pasar el tipo que queremos producir, y luego podemos regresar a la instancia que necesita.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Texter : MonoBehaviour {
    
    

    void Start()
    {
    
    
        VW vW = (VW) Clientele.Clienteles("VW");
        vW.Production();

        GeelyAutomobile geelyAutomobile = (GeelyAutomobile)Clientele.Clienteles("GeelyAutomobile");
        geelyAutomobile.Production();

        RedFlagCar redFlagCar = (RedFlagCar)Clientele.Clienteles("RedFlagCar");
        redFlagCar.Production();
    }
}

Lanza el script Test.cs a la escena, ejecútalo y echa un vistazo
Inserte la descripción de la imagen aquí

Modo de observador

Correspondiente al mecanismo de eventos, agregando oyentes para obtener cambios de estado.

La principal solución:

El patrón de observador dibuja un límite claro entre los módulos y mejora la capacidad de mantenimiento y la reutilización de la aplicación (esta oración proviene de la Enciclopedia Baidu).
Explique la oración anterior con mi propio entendimiento. El uso del patrón de observador puede evitar llamadas directas entre clases y reducir el acoplamiento, es decir, la clase A necesita monitorear la clase B, pero puede ejecutarse incluso si la clase B no está presente.

Cuándo usarlo: cuando cambia el estado de un objeto (objeto de destino), todos los objetos dependientes (objetos de observador) serán notificados y transmitidos notificaciones.

Aplicaciones:

1. Durante la subasta, el subastador observa la oferta más alta y luego informa a otros postores que oferten.
2. En Journey to the West, Wukong le pidió al Bodhisattva que entregara al Niño Rojo. El Bodhisattva roció agua en el suelo y atrajo a una tortuga vieja. Esta tortuga era el observador. Observó la acción del Bodhisattva rociando agua.
3. El ejemplo encontrado es la comunicación entre la capa inferior y la capa superior. El marco está diseñado para mantener una dependencia unidireccional, es decir, la capa superior depende de la capa inferior, la capa de visualización obtiene datos de la capa empresarial, y la capa empresarial depende de la biblioteca de clases básica.
Pero la capa inferior también necesita obtener el cambio de estado de la capa superior.Para no violar el principio de dependencia unidireccional, el modo de observador puede usarse para monitorear la capa superior para obtener el cambio de estado.

ventaja:

1. El observador y lo observado están acoplados de forma abstracta.
2. Establezca un mecanismo de activación.

Desventajas:

1. Si un objeto observado tiene muchos observadores directos e indirectos, tomará mucho tiempo notificar a todos los observadores.
2. Si hay una dependencia circular entre el observador y el objetivo de observación, el objetivo de observación activará una llamada cíclica entre ellos, lo que puede hacer que el sistema falle.
3. El modo de observador no tiene un mecanismo correspondiente para que el observador sepa cómo ha cambiado el objetivo observado, pero solo sabe que el objetivo observado ha cambiado.

Modo de comando

El modo de comando es un modo en el que el estado y el comportamiento del objeto se encapsulan y procesan de acuerdo con ciertas reglas.

La solución principal: puede separar al solicitante del comportamiento del implementador del comportamiento. Por ejemplo, si necesita comenzar a grabar en el juego, debe registrar las instrucciones de entrada. Si el solicitante del comportamiento y el implementador son estrechamente acoplado (ejecutar presionando el botón) No es propicio para la grabación.

ventaja:

1. Reducir el grado de acoplamiento del sistema.
2. Se pueden agregar fácilmente nuevos comandos al sistema.
3. La primera ventaja de este modo es reducir el grado de acoplamiento, como en el ejemplo anterior. En segundo lugar, debido a que el solicitante está separado de la implementación, podemos realizar muchas operaciones en las instrucciones solicitadas, como agregar nuevas instrucciones, modificar instrucciones, etc.

Ejemplo: En realidad encontré un ejemplo de comunicación entre módulos. Por ejemplo, mi juego tiene un módulo de inicio de sesión y un módulo de red. Cuando el módulo de inicio de sesión recibe la información de inicio de sesión, necesita enviar información al servidor para su verificación a través del módulo de red. Si lo llama directamente La función XXX del módulo de red. Suponiendo que esta función no se ha escrito o incluso escrito, el juego no se puede ejecutar y depurar. En este momento, puede escribir un administrador de módulo. Si necesita llamar a otro módulo función, puede enviar un mensaje al módulo. El administrador envía la información, y si el módulo no existe, almacena en caché la información y luego la envía cuando está disponible. Se trata de un desacoplamiento estático, es decir, un desacoplamiento durante la compilación, y puede ejecutarse incluso si aún no hay otro módulo disponible.

Para complementar los dos patrones de diseño, puede echar un vistazo. Si hay algún problema o error, todos son bienvenidos a plantearlos, ¡gracias! ! !
El seguimiento lo agregará y lo escribirá aquí hoy.
Gracias a todos por su apoyo.

Supongo que te gusta

Origin blog.csdn.net/m0_47605113/article/details/111589335
Recomendado
Clasificación