Prototipo (patrón de diseño)

La versión actual de la página aún no ha sido revisada por colaboradores experimentados y puede diferir significativamente de la versión revisada el 9 de marzo de 2016; las comprobaciones requieren 11 ediciones .
Prototipo
prototipo
Tipo de generando
Descrito en Patrones de diseño

Prototipo , ( ing.  Prototipo )  - patrón de diseño de generación .

Cita

Especifica los tipos de objetos que se crearán utilizando una instancia de prototipo y crea nuevos objetos copiando este prototipo. Le permite alejarse de la implementación y le permite seguir el principio de "programación a través de interfaces". Una interfaz/clase abstracta en la parte superior de la jerarquía se especifica como el tipo de retorno, y las clases descendientes pueden sustituir a un heredero que implemente este tipo allí.

En pocas palabras, este es el patrón de crear un objeto mediante la clonación de otro objeto en lugar de crearlo a través de un constructor.

Aplicación

El patrón se utiliza para:

Utilice este patrón de diseño cuando al sistema no le importe cómo se crean, empaquetan y presentan los productos en él:

Ejemplos

Ejemplo de Python

Código fuente en Python #!/usr/bin/env python # -*- codificación: utf-8 -*- importar copia Prototipo de clase : def __init__ ( auto ): auto . _objetos = {} def registrar_objeto ( self , nombre , obj ): """Registrar un objeto""" self . _objetos [ nombre ] = obj def unregister_object ( self , name ): """Anular el registro de un objeto""" del self . _objetos [ nombre ] def clone ( self , nombre , ** attr ): """Clonar un objeto registrado y actualizar el diccionario de atributos internos""" obj = copiar . copia profunda ( self . _objects . get ( nombre )) obj . __dict__ . actualizar ( attr ) devolver obj clase A : def __init__ ( auto ): auto . x = 3 propio . y = 8 propio . z = 15 propio . basura = [ 38 , 11 , 19 ] def __str__ ( self ): devuelve ' {} {} {} {} ' . formato ( self . x , self . y , self . z , self . trash ) def principal (): a = A () prototipo = prototipo () prototipo . registrarse_objeto ( 'objetoa' , a ) b = prototipo . clon ( 'objeto' ) c = prototipo . clonar ( 'objeto' , x = 1 , y = 2 , basura = [ 88 , 1 ]) imprimir ([ str ( i ) for i in ( a , b , c )]) si __nombre__ == '__principal__' : principal ()
      1. PRODUCCIÓN ###
  1. ['3 8 15 [38, 11, 19]', '3 8 15 [38, 11, 19]', '1 2 15 [88, 1]']

Ejemplo de C++

Texto fuente en C++ comida de clase { público : comida virtual ~ (); vacío virtual comer () = 0 ; comida virtual * clon () const = 0 ; //... }; clase de espagueti : comida pública { público : Espagueti ( const Spaghetti & ); anular comer (); Spaghetti * clon () const { return new Spaghetti ( * this ); } //... };

Ejemplo de Java

Fuente Java /** * Clase prototipo */ clase pública Cookie implementa Clonable { peso int protegido ; @Override public Cookie clone () arroja CloneNotSupportedException { Cookie copy = ( Cookie ) super . clonar (); //En una implementación real de este patrón, ahora puede cambiar las referencias a //las piezas costosas de producir a partir de las copias que se encuentran dentro del prototipo. devolver copia ; } } /** * Prototipos concretos para clonar */ public class CoconutCookie extends Cookie { } /** * Clase de cliente */ public class CookieMachine { cookie privada cookie ; // Podría haber sido una cookie Clonable privada. CookieMachine público ( Cookie cookie ) { este . galleta = galleta _ } Cookie pública makeCookie () lanza CloneNotSupportedException { return ( Cookie ) this . galleta _ clonar (); } public static void main ( String args [] ) lanza CloneNotSupportedException { Cookie tempCookie = null ; Cookie prot = new CoconutCookie (); CookieMachine cm = new CookieMachine ( prot ); for ( int i = 0 ; i < 100 ; i ++ ) tempCookie = cm . hacerCookie (); } }

Ejemplo de Scala

Código fuente de Scala paquete.com _ prototipo de objeto de paquete { class Waffle ( nombre de var protegido : Cadena , relleno primario de var protegido : Cadena , relleno especial de var protegido : Opción [ Cadena ] = Ninguno ) extiende Cloneable { anular def clon (): Waffle = { super . clon (). comoInstanciaDe [ Waffle ] } def salida () : Unidad = { println ( s"Waffle $ nombre con relleno primario $ relleno primario " + ( if ( relleno especial != Ninguno ) relleno especial . get else "" )) } } objeto Prueba de prototipo { def main ( args : Array [ String ]) : Unit = { println ( "Output:" ) val chocolateWaffle = new Waffle ( "ChocolateWaffle" , "Chocolate" ) chocolateWaffle . salida () galleta de chocolate . clon (). salida () val cocoWaffle = new Waffle ( "CocoWaffle" , "Leche condensada" , Algunos ( "Coco" ))) cocoWaffle . salida () cocoWaffle . clon (). salida () } } } // Salida: // Waffle ChocolateWaffle con relleno primario Chocolate // Waffle ChocolateWaffle con relleno primario Chocolate // Waffle CocoWaffle con relleno primario Leche condensadaCoco // Waffle CocoWaffle con relleno primario Leche condensadaCoco

Ejemplo en C#

Texto fuente en C# utilizando el sistema ; espacio de nombres Prototipo { class MainApp { static void Main () { // Crear dos instancias y clonar cada Prototipo prototipo1 = new ConcretePrototype1 ( "I" ); Prototipo clonadoPrototipo1 = prototipo1 . clonar (); consola _ WriteLine ( "Clonar: {0}" , clonedPrototype1 . Id ); Prototipo prototipo2 = new ConcretePrototype2 ( "II" ); Prototipo clonadoPrototipo2 = prototipo2 . clonar (); consola _ WriteLine ( "Clonado: {0}" , clonedPrototype2 . Id ); } } // "Prototipo" public abstract class Prototype { // Constructor public Prototype ( string id ) { this . identificación = identificación ; consola _ Write ( "Se llama al constructor base." ); } // Propiedad public string Id { get ; conjunto privado ; } public virtual Prototype Clone () { // Copia superficial devuelve ( Prototype ) this . MemberwiseClone (); } } // "ConcretePrototype1" public class ConcretePrototype1 : Prototype { // Constructor public ConcretePrototype1 ( string id ) : base ( id ) { } } // "ConcretePrototype2" public class ConcretePrototype2 : Prototype { // Constructor public ConcretePrototype2 ( string id ) : base ( id ) { } } }

Ejemplo de PHP

codigo fuente php

<?php /** * Jerarquía de clases válidas para prototipos */ clase abstracta Terreno {} clase abstracta Mar se extiende Terreno {} clase TierraMar se extiende Mar {} clase MarsSea se extiende Mar {} clase VenusSea se extiende Mar {} abstract class Plains extends Terrain {} class EarthPlains extends Plains {} class MarsPlains extends Plains {} class VenusPlains extends Plains {} clase abstracta Forest extiende el terreno {} clase EarthForest extiende el bosque {} clase MarsForest extiende el bosque {} clase VenusForest extiende el bosque {} /** * Definición de la lógica de la fábrica de prototipos */ class TerrainFactory { private $sea ; $bosque privado ; llanuras privadas ; public function __construct ( Mar $mar , Llanuras $llanuras , Bosque $bosque ) { $esto -> mar = $mar ; $esto -> llanuras = $llanuras ; $esto -> bosque = $bosque ; } function getSea ( ) { return clon $this -> sea ; } function getPlains ( ) { return clon $this -> plains ; } function getForest ( ) { return clon $this -> forest ; } } /** * Crear una fábrica con los parámetros de prototipo dados */ $prototypeFactory = new TerrainFactory ( new EarthSea (), new MarsPlains (), new VenusForest () ); /** * Crea los objetos dados clonándolos */ $sea = $prototypeFactory -> getSea (); $planicies = $prototypeFactory -> getPlains (); $bosque = $prototypeFactory -> getForest ();

Ejemplo de rubí

código fuente rubí prototipo de módulo # "prototipo" prototipo de clase # Propiedad # la propiedad id está inicialmente presente para cada objeto, por lo que usaremos la propiedad de nombre attr_reader :nombre # constructor def inicializar nombre @nombre = fin de nombre final final # Crear una instancia y clonarla p1 = Prototipo :: Prototipo . new "my name" # el objeto de la clase Prototype se crea de la manera tradicional - por el método new p2 = p1 . clon # el método de clonación existe en cada objeto de forma predeterminada; no es necesario definirlo puts "p1.id = #{ p1 . object_id } , p2.id = #{ p2 . object_id } " # IDs diferentes serán impresos puts "p1.name = #{ p1 . name } , p2.name = #{ p2 .name } " # se imprimirán nombres idénticos - "mi nombre " # Espere a que el usuario obtenga

Ejemplo de VB.NET

Texto fuente en lenguaje VB.NET Espacio de nombres Prototipo Clase MainApp Shared Sub Main () ' Crear dos instancias y clonar cada una Dim p1 As Prototype = New ConcretePrototype1 ( "I" ) Dim c1 As Prototype = p1 . Clonar () Consola . WriteLine ( "Clonar: {0 } " , c1.Id ) Dim p2 As Prototype = New ConcretePrototype2 ( "II" ) Dim c2 As Prototype = p2 . Clonar () Consola . WriteLine ( "Clonar: {0}" , c2 . Id ) consola _ Lectura () End Sub End Class ' "Prototipo" MustInherit Class Prototype Private m_id As String 'Constructor Public Sub New ( ByVal id As String ) Me . m_id = id End Sub ' ID de propiedad pública de solo lectura () como cadena Obtener Retorno m_id End Obtener propiedad final Función pública MustOverride Clone () como clase final de prototipo ' "PrototipoConcreto1" Clase ConcretePrototype1 Hereda Prototype ' Constructor Public Sub New ( ByVal id As String ) MyBase . Nuevo ( id ) End Sub Public Overrides Function Clone () As Prototype ' Incomplete copy Return DirectCast ( Me . MemberwiseClone (), Prototype ) End Function End Class ' "PrototipoConcreto2" Clase ConcretePrototype2 hereda prototipo 'Constructor Public Sub New ( ByVal id As String ) MyBase . Nuevo ( id ) End Sub Public Overrides Function Clone () As Prototype ' Incomplete copy Return DirectCast ( Me . MemberwiseClone (), Prototype ) End Function End Class End Namespace

Ejemplo de Delphi

Texto fuente en Delphi programa PrototipoPatrón ; {$CONSOLA DE TIPO DE APLICACIÓN} utiliza SysUtils ; type TPrototype = class public function Clone : ​​TPrototype ; virtuales ; abstracto ; fin ; tipo TPrototypeType = clase ( TPrototype ) private FID : Integer ; FInfo : cadena ; ID de propiedad pública : entero leer FID escribir FID ; propiedad Información : Cadena leer FInfo escribir FInfo ; clon de función : TPrototype ; anular ; fin ; función TPrototypeType . Clon : T Prototipo ; var vClone : ​​TPrototypeType ; comenzar vClone := TPrototypeType . crear ; vClonar . identificación := identificación ; vClonar . Información := Información ; Resultado := vClone ; fin ; procedimiento CloneAndShow ( Prototipo : TPrototypeType ) ; var vClone : ​​TPrototypeType ; comenzar vClone := Prototipo . clonar ; intente Escribir ( vClone . ID ) ; Escribir ( vClone.Info ) ; _ _ finalmente vClone . Gratis ; fin ; EscribirLn ; fin ; var vConcretePrototype1 , vConcretePrototype2 : TPrototypeType ; comenzar vConcretePrototype1 := TPrototypeType . crear ; vConcretePrototype2 := TPrototypeType . crear ; prueba vConcretePrototype1 . identificación := 10 ; vConcretePrototype1 . Información := '¡Prototipo1!' ; vConcretePrototype2 . identificación := 11 ; vConcretePrototype2 . Información := '¡Prototipo2!' ; Clonar y mostrar ( vConcretePrototype1 ) ; Clonar y mostrar ( vConcretePrototype2 ) ; finalmente vConcretePrototype1 . Gratis ; vConcretePrototype2 . Gratis ; fin ; Leerln ; fin _

Ejemplo de CoffeeScript

Ejemplo de CoffeeScript clase PresidentePrototipo constructor: (@proto) -> clon: -> cliente = nuevo Presidente () cliente.primero = @proto . primer cliente.último = @proto . último cliente.aka = @proto . también conocido como cliente constructor del presidente de la clase : (@first, @last, @aka) -> say: -> console . log "Su nombre es #{ @first } #{ @last } alias #{ @aka } ." ejecutar = -> proto = nuevo presidente ( "Jimmy" , "Gales" , "Jimbo" ) prototipo = nuevo presidente Prototipo ( proto ) cliente = prototipo . clon () cliente . decir () correr ()

ejemplo Io

código fuente de io Foo := Objeto clon Foo smth := 2 Bar := Foo clon

Literatura

  • E. Gamma, R. Helm, R. Johnson, J. Vlissides . Técnicas de diseño orientado a objetos. Patrones de Diseño = Patrones de Diseño: Elementos de Software Reutilizable Orientado a Objetos. - San Petersburgo. : "Pedro" , 2007. - S. 366. - ISBN 978-5-469-01136-1 . (también ISBN 5-272-00355-1 )

Véase también

Enlaces