El patrón de diseño Prototype
Descripción
El objetivo del patrón de diseño Prototype es la creación de nuevos objetos mediante la clonación de objetos existentes.
Ejemplo
Durante la compra de un vehículo, un cliente debe recibir una documentación compuesta por un número concreto de documentos tales como el certificado de cesión, la solicitud de matriculación o incluso la orden de pedido. Existen otros tipos de documentos que pueden incluirse o excluirse de esta documentación en función de las necesidades de gestión o de cambios de reglamentación.
En primer lugar, creamos un modelo de documentación que consiste en una instancia de la clase DocumentacionEnBlanco y que contiene los distintos documentos necesarios, documentos que se quedarán en blanco. De este modo definimos a nivel de las instancias, y no a nivel de las clases, el contenido preciso de la documentación que debe recibir un cliente. Incluir o excluir un documento en la documentación en blanco no supone ninguna modificación en su clase.
Una vez presentada la documentación en blanco, recurrimos al proceso de clonación para crear las nuevas documentaciones. Cada nueva documentación se crea duplicando todos los documentos de la documentación en blanco, que constituye una especie de modelo básico para todas las documentaciones que se creen.
Esta técnica basada en objetos que poseen la capacidad de clonación utiliza el patrón de diseño Prototype, y los documentos constituyen los distintos prototipos.
La figura 7.1 ilustra...
Estructura
1. Diagrama de clases
La figura 7.2 detalla la estructura genérica del patrón de diseño Prototype.
![images/figure7-2.png images/figure7-2.png](https://www.eni-training.com/download/a7e0f116-7bba-4d53-b8e1-b6e04b2bdab7/images/figure7-2.png?id=AAEAAAD%2f%2f%2f%2f%2fAQAAAAAAAAAMAgAAAE1FbmkuRWRpdGlvbnMuTWVkaWFwbHVzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAUBAAAAJ0VuaS5FZGl0aW9ucy5NZWRpYXBsdXMuQ29tbW9uLldhdGVybWFyawIAAAAHcGlzVGV4dAlwaWR0ZURhdGUBAA0CAAAABgMAAAAwdGVzdCB2Ml84IC0gZmZhNjQzOWQtZDZjYi00NzYxLWJhYTMtZWZkZDNiZDcwMWM25rSq0F7p2IgL)
Figura 7.2 - Estructura del patrón de diseño Prototype
2. Participantes
Los participantes del patrón de diseño Prototype son los siguientes:
-
Cliente (AbstractDocumentacion, DocumentaciónCliente, DocumentacionEnBlanco) es una clase compuesta por un conjunto de objetos llamados prototipos, instancias de la clase abstracta Prototype. La clase Cliente necesita duplicar estos prototipos sin tener por qué conocer ni la estructura interna del Prototype ni la jerarquía de sus subclases.
-
Prototype (AbstractDocumento) es una clase abstracta de objetos capaces de duplicarse a sí mismos. Incluye la firma del método duplica.
-
PrototypeConcreto1 y PrototypeConcreto2 (OrdenDePedido, SolicitudMatriculación, CertificadoCesión) son las subclases concretas de Prototype que definen completamente un prototipo e implementan el método duplica.
3. Colaboración
El cliente solicita a uno o varios prototipos que se dupliquen a sí mismos.
Dominios de uso
El patrón de diseño Prototype se utiliza en los dominios siguientes:
-
Un sistema de objetos debe crear instancias sin conocer la jerarquía de clases que las describen.
-
Un sistema de objetos debe crear instancias de clases cargadas dinámicamente.
-
El sistema de objetos debe permanecer simple y no incluir una jerarquía paralela de clases de fabricación.
Ejemplo en PHP
El código fuente de la clase abstracta AbstractDocumento y de sus subclases concretas aparece a continuación. El método duplica utiliza la instrucción clone que proporciona PHP.
La instrucción clone de PHP nos evita tener que copiar manualmente cada atributo. En consecuencia, es posible implementar el método duplica completamente en la clase abstracta AbstractDocumento.
<?php
declare(strict_types=1);
namespace ENI\DesignPatterns\Prototype;
abstract class AbstractDocumento
{
protected string $contenido;
public function duplica(): self
{
return clone $this;
}
public function rellena(string $informaciones): void
{
$this->contenido = $informaciones;
}
abstract public function imprime(): void;
abstract public function muestra(): void;
}
<?php
declare(strict_types=1);
namespace ENI\DesignPatterns\Prototype;
class OrdenDePedido extends AbstractDocumento
{
public function muestra(): void
{
echo "Muestra el formulario de pedido: $this->contenido" .
PHP_EOL;
}
public function imprime(): void
{
echo "Imprime el formulario de pedido: $this->contenido" .
PHP_EOL;...