# Prototipo (patrón de diseño)

El patrón de diseño prototipo tiene como finalidad crear nuevos objetos clonando una instancia creada previamente. Este patrón especifica la clase de objetos a crear mediante la clonación de un prototipo que es una instancia ya creada. La clase de los objetos que servirán de prototipo deberá incluir en su interfaz la manera de solicitar una copia, que será desarrollada luego por las clases concretas de prototipos.

## Motivación

Este patrón resulta útil en escenarios donde es impreciso abstraer la lógica que decide qué tipos de objetos utilizará una aplicación, de la lógica que luego usarán esos objetos en su ejecución. Los motivos de esta separación pueden ser variados, por ejemplo, puede ser que la aplicación deba basarse en alguna configuración o parámetro en tiempo de ejecución para decidir el tipo de objetos que se debe crear. En ese caso, la aplicación necesitará crear nuevos objetos a partir de modelos. Estos modelos, o prototipos, son clonados y el nuevo objeto será una copia exacta de los mismos, con el mismo estado. Esto resulta interesante para crear, en tiempo de ejecución, copias de objetos concretos inicialmente fijados, o también cuando sólo existe un número pequeño de combinaciones diferentes de estado para las instancias de una clase.
Dicho de otro modo, este patrón propone la creación de distintas variantes de objetos que la aplicación necesite, en el momento y contexto adecuado. Toda la lógica necesaria para la decisión sobre el tipo de objetos que usará la aplicación en su ejecución se hace independiente, de manera que el código que utiliza estos objetos solicitará una copia del objeto que necesite. En este contexto, una copia significa otra instancia del objeto. El único requisito que debe cumplir este objeto es suministrar la funcionalidad de clonarse.
En el caso de un editor gráfico, se pueden crear rectángulos, círculos u otros, como copias de prototipos. Estos objetos gráficos pertenecerán a una jerarquía cuyas clases derivadas implementarán el mecanismo de clonación.

## Estructura

En la imagen siguiente se puede ver la estructura del patrón:
Creación de pantalón y blusas

## Participantes

Cliente: es el encargado de solicitar la creación de los nuevos objetos a partir de los prototipos.
Prototipo Concreto: posee características concretas que serán reproducidas para nuevos objetos e implementa una operación para clonarse.
Prototipo: declara una interfaz para clonarse, a la que accede el cliente.

## Colaboraciones

El cliente solicita al prototipo que se clone.

## Consecuencias

Aplicar el patrón prototipo permite ocultar las clases producto (prototipos concretos) del cliente y permite que el cliente trabaje con estas clases dependientes de la aplicación sin cambios.
Además, hace posible añadir y eliminar productos en tiempo de ejecución al invocar a la operación clonar, lo que supone un método que proporciona una configuración dinámica de la aplicación.
Este patrón permite la especificación de nuevos objetos generando un objeto con valores por defecto sobre el que posteriormente se podrán aplicar cambios. La especificación de nuevos objetos también puede realizarse mediante la variación de su estructura. Reducción del número de subclases.

## Desventajas

La jerarquía de prototipos debe ofrecer la posibilidad de clonar un elemento y esta operación puede no ser sencilla de implementar. Por otro lado, si la clonación se produce frecuentemente, el coste puede ser importante.

## Otros detalles
### Clonación profunda frente a clonación superficial

Entre las diferentes modalidades entre las que puede optar a la hora de implementar la clonación de un objeto prototipo, cabe destacar dos maneras de realizar la clonación: superficial y profunda.
En la primera de ellas un cambio sobre el objeto asociado con un clon afecta al objeto original, porque los objetos relacionados son los mismos (es decir, la clonación replica sólo el propio objeto y su estado, no sus asociaciones con terceros objetos), mientras que en la clonación profunda se clonan los objetos y también sus objetos relacionados.

### Uso en Java

En Java existe la interfaz cloneable y del Object Clone throws CloneNotSupportedException para llevar a cabo la implementación del prototipo de manera compatible con los prototipos ya existentes en las librerías Java.

### Negociador de productos

Una modificación o derivación de este patrón es el conocido como Negociador de Productos (Product Trader), que se centra en el tratamiento de los prototipos cuando varios clientes trabajan sobre ellos. Este patrón incorpora un gestor, normalmente utilizando el patrón de instancia única (singleton), que actúa sobre un conjunto de prototipos frente a los clientes.

## Implementación

Esta es una solución en el lenguaje PHP. En este ejemplo se tiene una clase abstracta PrototipoLibro, con dos subclases concretas: PrototipoLibroPHP y PrototipoLibroSQL.
Esta es una solución en el lenguaje C.Sharp de DotNet:
Esta es otra implementación distinta en el lenguaje Java:
* Datos: Q928696