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 , ( 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:
- para evitar esfuerzos adicionales para crear un objeto de forma estándar (es decir, el uso de un constructor, ya que en este caso también se llamará a los constructores de toda la jerarquía de los ancestros del objeto), cuando esto es prohibitivamente costoso para la aplicación.
- evite heredar el creador del objeto en la aplicación cliente, como lo hace el patrón de fábrica abstracta .
Utilice este patrón de diseño cuando al sistema no le importe cómo se crean, empaquetan y presentan los productos en él:
- las clases instanciadas se determinan en tiempo de ejecución, por ejemplo mediante carga dinámica;
- evitar construir jerarquías de clases o fábricas paralelas a la jerarquía de clases de productos;
- las instancias de clase pueden estar en uno de varios estados diferentes. Puede ser más conveniente establecer el número apropiado de prototipos y clonarlos, en lugar de instanciar manualmente la clase en el estado apropiado cada vez.
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 ()
- PRODUCCIÓN ###
- ['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