Modo de diseño | Modo de prototipo

1 | Descripción general del modo Prototipo

El modo de prototipo es un modo de creación especial, que obtiene objetos más idénticos o similares copiando un objeto existente. El modo de prototipo puede mejorar la eficiencia de la creación de objetos del mismo tipo en el sistema y simplificar el proceso de creación. 

En "Journey to the West", la historia de "Sun Wukong arrancando el pelo y volviéndose mono" es casi conocida por todo el mundo. El pelo de mono utilizó pelo de mono para copiar muchos "avatares" que son exactamente iguales a los suyos. Este tipo de escena se denomina modo prototipo en el campo del diseño de software orientado a objetos, y Monkey King se denomina objeto prototipo.

Definición de patrón de prototipo

  • Modo de prototipo: utilice una instancia de prototipo para especificar el tipo de objeto que se creará y cree un nuevo objeto copiando este prototipo.
  • Patrón de prototipo: especifique los tipos de objetos que se crearán utilizando una instancia típica de prototipo y cree nuevos objetos copiando este tipo de prototipo.

Cómo funciona el modo prototipo

  • Pasar un objeto prototipo al objeto a crear (es decir, el objeto cliente), y el objeto a crear realiza el proceso de creación de un nuevo objeto solicitando al objeto prototipo que se copie a sí mismo. Este proceso de creación de nuevos objetos también se denomina "clonación de objetos". La fábrica para crear nuevos objetos es la clase prototipo en sí, y el método de fábrica se implementa mediante el método de clonación responsable de copiar el objeto prototipo.

Nota: Los objetos creados mediante la clonación de objetos son objetos completamente nuevos y tienen nuevas direcciones en la memoria. Por lo general, el nuevo objeto producido por el clon no tendrá ningún efecto sobre el objeto prototipo y cada objeto clonado es independiente entre sí. Después de modificar el objeto clonado, se pueden obtener una serie de objetos similares pero incompletos.

2 | La estructura y realización del patrón prototipo

2.1 La estructura del modelo prototipo

El modo de prototipo contiene los siguientes 3 roles:

  • (1) Prototipo (clase de prototipo abstracto) : Es la interfaz que declara el método de clonación, y es la clase principal común de todas las clases de prototipos concretos. Puede ser una clase abstracta o una interfaz, o incluso una clase de implementación concreta.
  • (2) ConcretePrototvpe (clase de prototipo concreto) : implementa el método de clonación declarado en la clase de prototipo abstracto y devuelve un objeto de clonación propio en el método de clonación.
  • (3) Cliente (Clase blanca de cliente) : en la clase de cliente, deje que un objeto prototipo se clone a sí mismo para crear un nuevo objeto. Solo necesita instanciar directamente o crear un objeto prototipo a través de métodos de fábrica, y luego llamar a los múltiples pares idénticos del objeto. se puede obtener mediante el método de clonación. Prntotvne es programado por Ganjia Baimi Company. Por lo tanto, los usuarios pueden elegir el arroz original específico de acuerdo con sus necesidades. Es muy conveniente eliminar algunas clases de prototipos.

2.2 Clon superficial y clon profundo del modo prototipo

Según si se copian las variables miembro del tipo de referencia contenidas en el objeto prototipo mientras se copia el objeto prototipo, el mecanismo de clonación del modo prototipo se divide en dos tipos: clonación superficial y clonación profunda, a veces denominada copia superficial y copia profunda.

(1) Clon superficial

En la clonación superficial, si los miembros del objeto prototipo también son castigos de clase de valor (como int, double, byte, bool, char y otros tipos de datos básicos), se copiará una copia en el objeto sometido. Si la variable miembro de el objeto prototipo es un tipo de referencia (como tipos de datos complejos como clases, interfaces, matrices, etc.), la dirección del objeto referenciado se copia en el objeto anulado, es decir, las variables miembro del objeto prototipo y el el objeto clonado apunta a la misma dirección de memoria. En pocas palabras, en la clonación superficial, cuando se copia el objeto prototipo, solo se copian las variables miembro de sí mismo y el tipo de valor contenido en él, mientras que las variables miembro del tipo de referencia no se copian.

(2) Clon profundo

En la clonación profunda, independientemente de si la variable miembro del objeto prototipo es un tipo de valor o un tipo de referencia, se copiará al objeto clonado y la clonación profunda también copiará todos los objetos de referencia del objeto prototipo al objeto clonado. En pocas palabras, en la clonación profunda, además de copiar el objeto en sí, también se copiarán todas las variables miembro contenidas en el objeto.

2.2 Implementación del modo prototipo

La clave para implementar el modo de prototipo es cómo implementar el método de clonación. Hay dos métodos de clonación de uso común en C #:

2.2.1 Método de implementación de clonación general , el código de muestra es el siguiente:

abstract class Prototype 
{
    public abstract Prototype Clone();
}

class ConcretePrototype : Prototype
{
    /// <summary>
    /// 成员变量
    /// </summary>
    public string Attr { get; set; }

    /// <summary>
    /// 克隆方法,通过赋值的方式来实现对象的复制。
    /// </summary>
    /// <returns></returns>
    public override Prototype Clone() => new ConcretePrototype
    {
        Attr = Attr //成员变量赋值
    };
}

 Código de muestra de llamada del cliente:

// 1.创建 ConcretePrototype 对象作为原型。
ConcretePrototype prototype = new ConcretePrototype();
// 2. 原型实例对象 prototype 调用克隆方法 Clone() 创建克隆对象。
ConcretePrototype copy = (ConcretePrototype)prototype.Clone();

 Nota: Este método es un método general del modo prototipo y no tiene nada que ver con las características del lenguaje de programación en sí. Además de C #, otros lenguajes de programación orientados a objetos también pueden usar este formulario para practicar la clonación del prototipo. objetos. En el método de clonación anterior Clone (), si la replicación se logra creando un nuevo objeto miembro, es un esquema de implementación de clonación profunda. El objeto string / String en lenguaje C # tiene particularidad, siempre que las dos cadenas sean iguales internamente, ya sea por asignación de valor o creación de un nuevo objeto, siempre tendrán una sola copia en la memoria. Para obtener más información, consulte " Mecanismo de residencia de cadenas de C # ".

Referencia: [Mecanismo de residencia e inmutabilidad de cadenas] https://www.cnblogs.com/SignX/p/10933482.html

2.2.2 Método MemberwiseClone () e interfaz ICloneable en C #

En el lenguaje C #, se proporciona un método MemberwiseClone () para implementar la clonación superficial. Este método es muy conveniente de usar, y el método MemberwiseClone () de un objeto existente se puede llamar en el medio para implementar la clonación de objetos. El código de muestra es el siguiente:

class Member { }

class ConcretePrototypeA 
{
    /// <summary>
    /// 成员变量
    /// </summary>
    public Member MyMember { get; set; }

    /// <summary>
    /// 克隆方法,通过赋值的方式来实现对象的复制。
    /// </summary>
    /// <returns></returns>
    public ConcretePrototypeA Clone() => (ConcretePrototypeA)this.MemberwiseClone(); //浅克隆      
}

 Se llama al cliente y el resultado de la prueba confirma que el método de clonación es una clonación superficial.

 La interfaz ICloneable actúa como una clase prototipo abstracta, y la clase prototipo concreta suele ser una subclase que implementa la interfaz. El código de muestra es el siguiente:

class ConcretePrototypeB: System.ICloneable
{
    /// <summary>
    /// 成员变量
    /// </summary>
    public Member MyMember { get; set; }

    /// <summary>
    /// 实现深克隆
    /// </summary>
    /// <returns></returns>
    public object Clone()
    {
        ConcretePrototypeB copy = this.MemberwiseClone() as ConcretePrototypeB; //对象转换
        Member newMember = new Member();
        copy.MyMember = newMember;
        return copy;
    }
}

Lo llama el cliente y el resultado de la prueba confirma que el método de clonación es una clonación profunda.

3 | Administrador de prototipos

El administrador de prototipos (Prototype Manager) almacena múltiples objetos prototipo en una colección para uso del cliente. Es una fábrica responsable de la clonación de objetos. Se define una colección para almacenar objetos prototipo. Si necesita un objeto prototipo Se puede obtener un clon copiando el objeto prototipo correspondiente en la colección. Programe la clase abstracta en el administrador de prototipos para una fácil extensión. La estructura es la siguiente:

 Implementación del código PrototypeManager PrototypeManager:

using System.Collections;

namespace PrototypePattern
{
    /// <summary>
    /// 原型管理器-PrototypeManager
    /// </summary>
    class PrototypeManager
    {
        #region SingleProfit 单例模式
        //创建私有化静态obj锁
        private static readonly object _ObjLock = new object();
        //创建私有静态字段,接收类的实例化对象
        private static volatile PrototypeManager _SingleProfit = null; //volatile 促进线程安全,保证线程有序执行 
        //构造函数私有化
        private PrototypeManager() { }
        //创建单利对象资源并返回
        public static PrototypeManager CreateSingleProfitObj()
        {
            if (_SingleProfit == null)
            {
                lock (_ObjLock)
                {
                    if (_SingleProfit == null)
                    {
                        _SingleProfit = new PrototypeManager();
                    }
                }
            }
            return _SingleProfit;
        } 
        #endregion

        /// <summary>
        /// Hashtable 存储原型对象
        /// </summary>
        private readonly static Hashtable hashTable = new Hashtable();

        /// <summary>
        /// Hashtable 新增原型对象
        /// </summary>
        /// <param name="key"></param>
        /// <param name="prototype"></param>
        public void Add(string key, Prototype prototype) 
        {
            hashTable.Add(key,prototype);
        }

        /// <summary>
        /// 获取克隆对象
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public Prototype Get(string key) 
        {
            Prototype copy = ((Prototype)hashTable[key]).Clone(); //通过(内置)克隆方法创建新对象
            return copy;
        }
    }
}

En el desarrollo real, la clase PrototypeManager generalmente se diseña como una clase singleton (modo singleton) para garantizar que haya uno y solo un objeto PrototypeManager en el sistema, que no solo ayuda a ahorrar recursos del sistema, sino que también puede controlar mejor el prototipo. objeto administrador. Agregue dos clases, ConcretePrototypeC y ConcretePrototypeD

#region 配合 PrototypeManager 使用
class ConcretePrototypeC : Prototype
{
    public override Prototype Clone()
    {
        return (ConcretePrototypeC) this.MemberwiseClone();
    }
}

class ConcretePrototypeD : Prototype
{
    public override Prototype Clone()
    {
        return (ConcretePrototypeD) this.MemberwiseClone();
    }
}
#endregion

Método de llamada del cliente

4 | Pros y contras del modo prototipo y el entorno aplicable

Como una forma de crear rápidamente una gran cantidad de objetos idénticos o similares, el modo de prototipo se usa ampliamente en el desarrollo de software. Las operaciones de copiar (Ctrl + C) y pegar (Ctrl + V) proporcionadas por muchos software son aplicaciones típicas del prototipo modo.

4.1 Las principales ventajas del modo prototipo

  • (1) Cuando la instancia de objeto a crear es más compleja, el uso del modo de prototipo puede simplificar el proceso de creación de objeto, y la creación de una instancia existente puede mejorar la eficiencia de la creación de una nueva instancia.
  • (2) La escalabilidad es mejor. Debido a que la clase de prototipo abstracto se proporciona en el modo de prototipo, el cliente puede programar el prototipo abstracto y la clase de prototipo específica se escribe en el archivo de configuración. Agregar o reducir clases de productos no tiene ningún efecto en el Sistema original. Cualquier impacto.
  • (3) El modelo de prototipo proporciona una estructura de creación simplificada. El modelo de método de fábrica a menudo necesita tener una estructura de jerarquía de fábrica que sea la misma que la jerarquía de clases de producto, mientras que el modelo de prototipo no necesita ser así. La copia del producto en el modelo de prototipo está encapsulado en la clase de tipo El método de clonación en la implementación no requiere una clase de fábrica especial para crear productos.
  • (4) Puede guardar el estado del objeto mediante la clonación profunda y usar el modo de prototipo para copiar el objeto y guardar su estado para usarlo cuando sea necesario (por ejemplo, para restaurar a un cierto estado histórico), lo que puede ayudar en la deshacer la operación.

4.2 Las principales desventajas del modelo prototipo

  • (1) Es necesario equipar cada clase con un método de clonación, y el método de clonación se ubica dentro de una clase. Cuando se modifica la clase existente, es necesario modificar el código fuente, lo que viola el principio de apertura y cierre .
  • (2) Es necesario escribir códigos más complejos al implementar la clonación profunda, y cuando hay múltiples referencias anidadas entre objetos, para lograr la clonación profunda, las clases correspondientes a cada capa de objetos deben soportar la clonación profunda, lo que puede ser difícil. para lograr algo difícil.

4.3 Entorno aplicable del modo prototipo

  • (1) El costo de crear un nuevo objeto es relativamente alto (por ejemplo, la inicialización lleva mucho tiempo y consume demasiados recursos de CPU o de red). El nuevo objeto se puede obtener copiando el objeto existente. Si es un objeto similar, puede usarlo Las variables miembro están ligeramente modificadas.
  • (2) El sistema necesita guardar el estado del objeto y el estado del objeto cambia muy poco.
  • (3) Es necesario evitar el uso de clases de fábrica jerárquicas para crear objetos jerárquicos, y el objeto de instancia de la clase tiene solo uno o unos pocos estados combinados. La nueva instancia obtenida al copiar el objeto prototipo puede ser mejor que usar el constructor para crear una nueva instancia Más conveniente.

Supongo que te gusta

Origin blog.csdn.net/ChaITSimpleLove/article/details/114805218
Recomendado
Clasificación