El patrón de diseño Template Method
Descripción
El patrón de diseño Template Method permite delegar en las subclases ciertas etapas de una de las operaciones de un objeto, estando estas etapas descritas en las subclases.
Ejemplo
En el sistema de venta online de vehículos, queremos gestionar pedidos de clientes de España y de Luxemburgo. La diferencia entre ambas peticiones concierne al cálculo del IVA. Si bien en España la tasa de IVA es siempre fija del 21%, en el caso de Luxemburgo existen cuatro tasas de IVA distintas (para hacerlo más sencillo, vamos a tomar un IVA estándar del 17%). Por lo tanto, el cálculo del IVA requiere dos operaciones de cálculo distintas en función del país.
Una primera solución consiste en implementar dos clases distintas sin superclase común: PedidoEspaña y PedidoLuxemburgo. Esta solución presenta el inconveniente importante de que tiene código idéntico que no ha sido factorizado, como por ejemplo la visualización de la información del pedido (método visualiza).
Podría incluirse una clase abstracta Pedido para factorizar los métodos comunes, como el método visualiza.
El patrón de diseño Template Method permite ir más lejos proponiendo factorizar el código común en el interior de los métodos. Tomemos el ejemplo del método calculaImporteConIVA cuyo algoritmo es el siguiente para España (escrito en pseudocódigo).
calculaImporteConIVA:
importeIVA = importeSinIVA * 0,21;
importeConIVA = importeSinIVA + importeIVA;
A su vez, el algoritmo para...
Estructura
1. Diagrama de clases
La figura 27.4 muestra la estructura genérica del patrón de diseño Template Method.
Figura 27.4 - Estructura del patrón de diseño Template Method
2. Participantes
Los participantes del patrón de diseño Template Method son los siguientes:
-
La clase abstracta ClaseAbstracta (AbstractPedido) incluye el método "modelo" así como la firma de los métodos abstractos que invoca este método.
-
La subclase concreta ClaseConcreta (PedidoEspana y PedidoLuxemburgo) implementa los métodos abstractos utilizados por el método "modelo" de la clase abstracta. Puede haber varias clases concretas.
3. Colaboraciones
La implementación del algoritmo se realiza mediante la colaboración entre el método "modelo" de la clase abstracta y los métodos de una subclase concreta que complementa el algoritmo.
Dominios de aplicación
El patrón de diseño Template Method se utiliza en los casos siguientes:
-
Una clase compartida con otra u otras clases con código idéntico que puede factorizarse siempre que las partes específicas a cada clase hayan sido desplazadas a nuevos métodos.
-
Un algoritmo posee una parte invariable y partes específicas a distintos tipos de objetos.
Ejemplo en PHP
La clase abstracta AbstractPedido incluye el método "modelo" calculaImporteConIVA que invoca al método abstracto calculaIva.
<?php
declare(strict_types=1);
namespace ENI\DesignPatterns\TemplateMethod;
abstract class AbstractPedido
{
protected float $importeSinIva;
protected float $importeIva;
protected float $importeConIva;
public function __construct(float $importeSinIva)
{
$this->importeSinIva = $importeSinIva;
}
public function calculaImporteConIva(): void
{
$this->calculaIva();
$this->importeConIva = $this->importeSinIva + $this->importeIva;
}
public function muestra(): void
{
echo 'Pedido' . PHP_EOL;
echo 'Importe sin IVA ' .
$this->formateaImporte($this->importeSinIva) .
PHP_EOL;
echo 'Importe con IVA' .
$this->formateaImporte($this->importeConIva). ...