El patrón de diseño Factory Method
Descripción
El objetivo del patrón de diseño Factory Method es proveer un método abstracto de creación de un objeto delegando en las subclases concretas su creación efectiva.
Ejemplo
Vamos a centrarnos en los clientes y sus pedidos. La clase abstracta Cliente implementa el método creaPedido que debe crear el pedido. Ciertos clientes solicitan un vehículo pagando al contado y otros clientes utilizan un crédito. En función de la naturaleza del cliente, el método creaPedido debe crear una instancia de la clase PedidoContado o una instancia de la clase PedidoCredito. Para realizar esta alternativa, el método creaPedido se define como abstracto. Ambos tipos de clientes se distinguen mediante dos subclases concretas de la clase abstracta Cliente:
-
La clase concreta ClienteContado cuyo método creaPedido crea una instancia de la clase PedidoContado.
-
La clase concreta ClienteCredito cuyo método creaPedido crea una instancia de la clase PedidoCredito.
Tal diseño está basado en el patrón de diseño Factory Method y el método creaPedido es el método de fabricación. El ejemplo se detalla en la figura 6.1.
Figura 6.1 - El patrón de diseño Factory Method aplicado a los clientes y sus pedidos
Estructura
1. Diagrama de clases
La figura 6.2 detalla la estructura genérica del patrón de diseño Factory Method.
Figura 6.2 - Estructura del patrón de diseño Factory Method
2. Participantes
Los participantes del patrón de diseño Factory Method son los siguientes:
-
CreadorAbstracto (AbstractCliente) es una clase abstracta que contiene la firma del método de fabricación y la implementación de métodos que invocan a este método de fabricación.
-
CreadorConcreto (ClienteContado, ClienteCredito) es una clase concreta que implementa el método de fabricación. Pueden existir varios creadores concretos.
-
Producto (AbstractPedido) es una clase abstracta que describe las propiedades comunes de los productos.
-
ProductoConcreto (PedidoContado, PedidoCredito) es una clase concreta que describe completamente un producto.
3. Colaboraciones
Los métodos concretos de la clase CreadorAbstracto se basan en la implementación del método de fabricación en las subclases. Esta implementación crea una instancia de la subclase adecuada de Producto.
Dominios de uso
El patrón de diseño Factory Method se utiliza en los casos siguientes:
-
Una clase que solo conoce las clases abstractas de los objetos con los que tiene relaciones.
-
Una clase quiere delegar en sus subclases las elecciones de instanciación apoyándose en el mecanismo del polimorfismo.
Ejemplo en PHP
El código fuente de la clase abstracta AbstractPedido y de sus dos subclases concretas aparece a continuación. El importe del pedido se pasa como parámetro al constructor de la clase. Si la validación de un pedido al contado es sistemática, hemos decidido, para nuestro ejemplo, aceptar únicamente aquellos pedidos provistos de un crédito cuyo valor se sitúe entre 1.000 y 5.000.
<?php
declare(strict_types=1);
namespace ENI\DesignPatterns\FactoryMethod;
abstract class AbstractPedido
{
protected float $cantidad;
public function __construct(float $cantidad)
{
$this->cantidad = $cantidad;
}
abstract public function valida(): bool;
abstract public function pago(): void;
}
<?php
declare(strict_types=1);
namespace ENI\DesignPatterns\FactoryMethod;
class PedidoContado extends AbstractPedido
{
public function pago(): void
{
$cantidad = number_format($this->cantidad, 2, ',', ' ');
echo...