¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Design Patterns en PHP
  3. El patrón de diseño Template Method
Extrait - Design Patterns en PHP Los 23 patrones de diseño: descripciones y soluciones ilustradas en UML2 y PHP (2ª edición)
Extractos del libro
Design Patterns en PHP Los 23 patrones de diseño: descripciones y soluciones ilustradas en UML2 y PHP (2ª edición) Volver a la página de compra del libro

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.

images/fig274.PNG

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). ...