El patrón de prototipo es un patrón de diseño de creación en el desarrollo de software . Se utiliza cuando el tipo de objetos a crear está determinado por una instancia prototípica , que se clona para producir nuevos objetos. Este patrón se usa para:
- evite las subclases de un creador de objetos en la aplicación cliente, como lo hace el patrón del método de fábrica .
- evite el costo inherente de crear un nuevo objeto de la manera estándar (por ejemplo, usando la palabra clave ' nuevo ') cuando es prohibitivamente costoso para una aplicación determinada.
Para implementar el patrón, declare una clase base abstracta que especifique un método clone () virtual puro . Cualquier clase que necesite una capacidad de " constructor polimórfico " se deriva de la clase base abstracta e implementa la operación clone () .
El cliente, en lugar de escribir código que invoca al operador "nuevo" en un nombre de clase codificado, llama al método clone () en el prototipo, llama a un método de fábrica con un parámetro que designa la clase concreta derivada deseada en particular, o invoca la clone () método a través de algún mecanismo proporcionado por otro patrón de diseño.
La división mitótica de una célula, que resulta en dos células idénticas, es un ejemplo de un prototipo que juega un papel activo en copiarse a sí mismo y, por lo tanto, demuestra el patrón de Prototipo. Cuando una célula se divide, resultan dos células de genotipo idéntico. En otras palabras, la célula se clona a sí misma. [1]
Descripción general
El patrón de diseño Prototype [2] es uno de los veintitrés patrones de diseño GoF bien conocidos que describen cómo resolver problemas de diseño recurrentes para diseñar software orientado a objetos flexible y reutilizable, es decir, objetos que son más fáciles de implementar, cambiar, probar y reutilizar.
El patrón de diseño de prototipos resuelve problemas como: [3]
- ¿Cómo se pueden crear objetos para que se puedan especificar qué objetos crear en tiempo de ejecución?
- ¿Cómo se pueden crear instancias de clases cargadas dinámicamente?
La creación de objetos directamente dentro de la clase que requiere (usa) los objetos es inflexible porque compromete la clase a objetos particulares en tiempo de compilación y hace que sea imposible especificar qué objetos crear en tiempo de ejecución.
El patrón de diseño del prototipo describe cómo resolver tales problemas:
- Defina un
Prototype
objeto que devuelva una copia de sí mismo. - Crea nuevos objetos copiando un
Prototype
objeto.
Esto permite la configuración de una clase con diferentes Prototype
objetos, que se copian para crear nuevos objetos, y aún más, Prototype
se pueden agregar y eliminar objetos en tiempo de ejecución.
Consulte también el diagrama de secuencia y clase UML a continuación.
Estructura
Diagrama de secuencia y clase UML
En el diagrama de clases de UML anterior , la Client
clase se refiere a la Prototype
interfaz para clonar un archivo Product
. La Product1
clase implementa la Prototype
interfaz creando una copia de sí misma.
El diagrama de secuencia UML muestra las interacciones en tiempo de ejecución: el Client
objeto llama clone()
a un prototype:Product1
objeto, que crea y devuelve una copia de sí mismo (un product:Product1
objeto).
Diagrama de clases UML
Reglas de juego
A veces, los patrones de creación se superponen; hay casos en los que el prototipo o la fábrica abstracta serían apropiados. En otras ocasiones, se complementan entre sí: la fábrica abstracta puede almacenar un conjunto de prototipos a partir de los cuales clonar y devolver objetos de producto ( GoF , p126). La fábrica abstracta, el constructor y el prototipo pueden usar singleton en sus implementaciones. (GoF, pág. 81, 134). Las clases de fábrica abstractas a menudo se implementan con métodos de fábrica (creación mediante herencia ), pero se pueden implementar mediante prototipos (creación mediante delegación ). (GoF, pág. 95)
A menudo, los diseños comienzan con el método de fábrica (menos complicado, más personalizable, proliferan las subclases) y evolucionan hacia una fábrica, un prototipo o un constructor abstractos (más flexibles, más complejos) a medida que el diseñador descubre dónde se necesita más flexibilidad. (GoF, pág. 136)
El prototipo no requiere subclases, pero requiere una operación de "inicialización". El método de fábrica requiere subclases, pero no requiere inicialización. (GoF, pág. 116)
Los diseños que hacen un uso intensivo de los patrones de composición y decoración a menudo también pueden beneficiarse de Prototype. (GoF, pág. 126)
La regla general podría ser que necesitaría clonar () un Objeto cuando desee crear otro Objeto en tiempo de ejecución que sea una copia fiel del Objeto que está clonando. Copia verdadera significa que todos los atributos del Objeto recién creado deben ser los mismos que los del Objeto que está clonando. Si pudiera haber creado una instancia de la clase usando new en su lugar, obtendría un Objeto con todos los atributos como sus valores iniciales. Por ejemplo, si está diseñando un sistema para realizar transacciones de cuentas bancarias, entonces querrá hacer una copia del Objeto que contiene la información de su cuenta, realizar transacciones en él y luego reemplazar el Objeto original por el modificado. En tales casos, querrá usar clone () en lugar de new.
Muestras de código
Pseudocódigo
Escribamos una clase de navegador de ocurrencias para un texto. Esta clase enumera las apariciones de una palabra en un texto. Un objeto de este tipo es costoso de crear, ya que las ubicaciones de las ocurrencias necesitan un proceso costoso para encontrarlas. Entonces, para duplicar tal objeto, usamos el patrón prototipo:
class WordOccurrences es un campo de ocurrencias es La lista del índice de cada aparición de la palabra en el texto. constructor WordOccurrences (texto, palabra) es input: el texto en el que se deben encontrar las ocurrencias input: la palabra que debe aparecer en el texto Vaciar la lista de ocurrencias para cada textIndex en text isMatchingg: = verdadero para cada palabra Índice en palabra si el carácter de la palabra actual no coincide con el carácter del texto actual, entonces isMatchingg: = falso si isMatching es verdadero , agregue el textIndex actual a la lista de ocurrencias método getOneOccurrenceIndex (n) es de entrada: un número a punto de la n º ocurrencia. salida: el índice de la n º ocurrencia. Devolver el n º elemento del ocurrencias campo si los hubiere. Se emite el método clone () : un objeto de WordOccurrences que contiene los mismos datos. Llame a clone () en la superclase. En el objeto devuelto, establezca el campo de ocurrencias con el valor del campo de ocurrencias locales . Devuelve el objeto clonado.texte: = "El patrón de prototipo es un patrón de diseño de creación en el desarrollo de software descrito por primera vez en patrones de diseño, el libro".wordw: = "patrón" dsearchEnginen: = new WordOccurrences (texto, palabra)otro motor de búsqueda: = motor de búsqueda.clone ()
(el algoritmo de búsqueda no está optimizado; es un algoritmo básico para ilustrar la implementación del patrón)
Ejemplo de C #
El tipo de objeto concreto se crea a partir de su prototipo. MemberwiseClone se utiliza en el método Clone para crear y devolver una copia de ConcreteFoo1 o ConcreteFoo2.
clase pública abstracta Foo { // implementación normal público abstracto Foo Clone (); }public class ConcreteFoo1 : Foo { public override Foo Clone () { return ( Foo ) this . MemberwiseClone (); // Clona la clase concreta. } }public class ConcreteFoo2 : Foo { public override Foo Clone () { return ( Foo ) this . MemberwiseClone (); // Clona la clase concreta. } }
Ejemplo de C ++
En las anotaciones de C ++ se proporciona una discusión del patrón de diseño junto con una implementación de ejemplo ilustrativa completa utilizando un diseño de clase polimórfica .
Ejemplo de Java
Este patrón crea el tipo de objeto utilizando su prototipo. En otras palabras, mientras crea el objeto del objeto Prototype, la clase crea un clon del mismo y lo devuelve como prototipo. El método de clonación se ha utilizado para clonar el prototipo cuando es necesario.
// Patrón de prototipo public abstract class Implementaciones de prototipo Cloneable { public Prototype clone () lanza CloneNotSupportedException { return ( Prototype ) super . clon (); } } public class ConcretePrototype1 extiende Prototype { @Override public Prototype clone () lanza CloneNotSupportedException { return ( ConcretePrototype1 ) super . clon (); } }public class ConcretePrototype2 extiende Prototype { @Override public Prototype clone () lanza CloneNotSupportedException { return ( ConcretePrototype2 ) super . clon (); } }
Ejemplo de PHP
// El patrón de prototipo en PHP se realiza con el uso de la función PHP incorporada __clone () prototipo de clase abstracta { cadena pública $ a ; cadena pública $ b ; función pública displayCONS () : void { echo "CONTRAS: { $ esto -> a } \ n " ; echo "CONTRAS: { $ esto -> b } \ n " ; } función pública displayCLON () : void { echo "CLON: { $ esto -> a } \ n " ; echo "CLON: { $ esto -> b } \ n " ; } función abstracta __clone (); }class ConcretePrototype1 extiende Prototype { public function __construct () { $ this -> a = "A1" ; $ esto -> b = "B1" ; $ esto -> displayCONS (); } función __clone () { $ esto -> displayCLON (); } }class ConcretePrototype2 extiende Prototype { public function __construct () { $ this -> a = "A2" ; $ esto -> b = "B2" ; $ esto -> displayCONS (); } function __clone () { $ esto -> a = $ esto -> a . "-C" ; $ esto -> b = $ esto -> b . "-C" ; $ esto -> displayCLON (); } }$ cP1 = new ConcretePrototype1 (); $ cP2 = new ConcretePrototype2 (); $ cP2C = clon $ cP2 ;// RESULTADO: # quanton81// CONTRAS: A1 // CONTRAS: B1 // CONTRAS: A2 // CONTRAS: B2 // CLON: A2-C // CLON: B2-C
Ejemplo de Python
Python versión 3.9+
importar copiaclase Prototipo : def clone ( self ): copia de retorno . copia profunda ( uno mismo )if __name__ == "__main__" : prototype = Prototype () prototype_copy = prototype . clonar () imprimir ( prototype_copy )
Producción:
<__ main __. Objeto prototipo en 0x7fae8f4e2940>
Ver también
Referencias
- ^ Duell, Michael (julio de 1997). "Ejemplos de patrones de diseño sin software". Revista de objetos . 7 (5): 54. ISSN 1055-3614 .
- ^ Erich Gamma; Richard Helm; Ralph Johnson; John Vlissides (1994). Patrones de diseño: elementos de software orientado a objetos reutilizable . Addison Wesley. págs. 117 y siguientes . ISBN 0-201-63361-2.
- ^ "El patrón de diseño del prototipo: problema, solución y aplicabilidad" . w3sDesign.com . Consultado el 17 de agosto de 2017 .
Fuentes
- Gamma, Erich ; Helm, Richard; Johnson, Ralph ; Vlissides, John (1994). Patrones de diseño: elementos de software orientado a objetos reutilizable . Addison-Wesley. ISBN 0-201-63361-2.