¡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 Decorator
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 Decorator

Descripción

El objetivo del patrón de diseño Decorator es agregar dinámicamente funcionalidades suplementarias a un objeto. Esta agregación de funcionalidades no modifica la interfaz del objeto y es totalmente transparente de cara a los clientes.

El patrón de diseño Decorator constituye una alternativa interesante a la creación de una subclase para enriquecer el comportamiento de un objeto.

Ejemplo

El sistema de venta de vehículos dispone de una clase VistaCatalogo que muestra, bajo el formato de un catálogo electrónico, los vehículos disponibles en una página web.

Queremos, a continuación, visualizar datos suplementarios para los vehículos "de alta gama", a saber la información técnica ligada al modelo. Para agregar esta funcionalidad, podemos crear una subclase de visualización específica para los vehículos "de alta gama". Si queremos visualizar el logo de la marca de los vehículos “de gamas media y alta”, vamos a tener que añadir una nueva subclase para esos vehículos, superclase de la clase de vehículos “de alta gama”, lo cual se vuelve rápidamente muy complejo.

Es fácil darse cuenta de que la herencia no está adaptada a lo que se demanda por dos motivos:

  • La herencia es una herramienta demasiado potente para agregar esta funcionalidad.

  • La herencia es un mecanismo estático.

El patrón de diseño Decorator proporciona otro enfoque que consiste en agregar un nuevo objeto llamado decorador que se sustituye por el objeto inicial y al mismo tiempo lo referencia. Este decorador posee la misma interfaz, lo cual vuelve a la sustitución perfectamente transparente de cara a los clientes. En nuestro caso, el método visualiza lo intercepta el decorador, que solicita...

Estructura

1. Diagrama de clases

La figura 13.4 detalla la estructura genérica del patrón de diseño Decorator.

images/7.png

Figura 13.4 - Estructura del patrón de diseño Decorator

2. Participantes

Los participantes del patrón de diseño Decorator son los siguientes:

  • ComponenteAbstracto (ComponenteGraficoVehículoInterfaz) es la interfaz común al componente y a los decoradores.

  • ComponenteConcreto (VistaVehiculo) es el objeto inicial al que se deben agregar las nuevas funcionalidades.

  • Decorador (AbstractDecorador) es una clase abstracta que guarda una referencia hacia un componente.

  • DecoradorConcretoA y DecoradorConcretoB (ModeloDecorador y MarcaDecorador) son subclases concretas de AbstractDecorador que tienen como objetivo implementar las funcionalidades agregadas al componente.

3. Colaboraciones

El decorador se sustituye totalmente al componente. Cuando recibe un mensaje destinado a este último, lo redirige hacia el componente realizando operaciones previas o posteriores.

Dominios de aplicación

El patrón de diseño Decorator puede utilizarse en los siguientes dominios:

  • Un sistema agrega dinámicamente funcionalidades a un objeto, sin modificar su interfaz, es decir sin que los clientes de este objeto tengan que sufrir posibles modificaciones.

  • Un sistema gestiona funcionalidades que pueden eliminarse dinámicamente.

  • El uso de la herencia para extender los objetos no es una solución pertinente, lo cual puede ocurrir cuando su jerarquía ya es de por sí bastante compleja.

Ejemplo en PHP

Presentamos a continuación el código fuente en PHP del ejemplo, comenzando por la interfaz ComponenteGraficoVehiculoInterfaz.

<?php  
 
declare(strict_types=1); 
 
namespace ENI\DesignPatterns\Decorator;  
 
interface ComponenteGraficoVehiculoInterfaz  
{ 
   public function visualiza(): void;  
} 

La clase VistaVehiculo implementa el método visualiza de la interfaz ComponenteGraficoVehiculoInterfaz.

<?php 
declare(strict_types=1); 
 
namespace ENI\DesignPatterns\Decorator;  
 
class VistaVehiculo implements ComponenteGraficoVehiculoInterfaz 
{  
   public function visualiza(): void  
   {  
       echo 'Visualización del vehículo' . PHP_EOL;  
   }  
} 

La clase AbstractDecorador implementa a su vez el método visualiza delegando la llamada en su componente, que es una dependencia inyectada en su constructor.

<?php  
 
declare(strict_types=1); µ
 * 
namespace ENI\DesignPatterns\Decorator;  
 
abstract class AbstractDecorador implements  
ComponenteGraficoVehiculoInterfaz  
{  
   protected ComponenteGraficoVehiculoInterfaz $componente; 
 
   public function __construct(ComponenteGraficoVehiculoInterfaz...