Middle
¿Cómo funciona un decorador en PHP?
sobes.tech AI
Respuesta de la IA
El patrón "Decorador" añade dinámicamente un nuevo comportamiento a un objeto existente envolviéndolo en otro objeto, llamado decorador.
-
Componentes:
- Interfaz (Component): Declara métodos comunes para el objeto original y sus decoradores.
- Componente Concreto (Concrete Component): Objeto principal que se desea decorar.
- Decorador Base (Decorator): Clase abstracta o interfaz que contiene una referencia a un objeto de la interfaz (Component) y implementa sus métodos, generalmente delegando la llamada a ese objeto.
- Decoradores Concretos (Concrete Decorators): Implementan nuevas funcionalidades, complementando o modificando el comportamiento del componente base.
-
Principio de funcionamiento:
- El decorador contiene una referencia al objeto que decora (composición).
- El decorador tiene la misma interfaz que el objeto decorado.
- Al llamar a un método en el decorador, este realiza lógica adicional antes o después de llamar al método correspondiente en el objeto decorado, o lo reemplaza completamente (aunque esto último no es un uso típico).
-
Ventajas:
- Permite agregar funcionalidad a los objetos en tiempo de ejecución, no en forma estática mediante herencia.
- Evita la "explosión" de la jerarquía de clases al combinar múltiples comportamientos diferentes.
- Permite crear combinaciones flexibles de comportamientos.
-
Ejemplo:
<?php
// Interfaz del componente
interface Coffee {
public function getCost(): float;
public function getDescription(): string;
}
// Componente concreto
class SimpleCoffee implements Coffee {
public function getCost(): float {
return 5.0;
}
public function getDescription(): string {
return "Café simple";
}
}
// Decorador base
abstract class CoffeeDecorator implements Coffee {
protected Coffee $coffee;
public function __construct(Coffee $coffee) {
$this->coffee = $coffee;
}
public function getCost(): float {
return $this->coffee->getCost();
}
public function getDescription(): string {
return $this->coffee->getDescription();
}
}
// Decorador concreto: Añadir leche
class MilkDecorator extends CoffeeDecorator {
public function getCost(): float {
return parent::getCost() + 2.0;
}
public function getDescription(): string {
return parent::getDescription() . ", con leche";
}
}
// Decorador concreto: Añadir azúcar
class SugarDecorator extends CoffeeDecorator {
public function getCost(): float {
return parent::getCost() + 1.0;
}
public function getDescription(): string {
return parent::getDescription() . ", con azúcar";
}
}
// Uso:
// Crear un café simple
$coffee = new SimpleCoffee();
echo $coffee->getDescription() . " - " . $coffee->getCost() . "\n"; // Café simple - 5
// Añadir leche
$coffeeWithMilk = new MilkDecorator($coffee);
echo $coffeeWithMilk->getDescription() . " - " . $coffeeWithMilk->getCost() . "\n"; // Café simple, con leche - 7
// Añadir azúcar
$coffeeWithMilkAndSugar = new SugarDecorator($coffeeWithMilk);
echo $coffeeWithMilkAndSugar->getDescription() . " - " . $coffeeWithMilkAndSugar->getCost() . "\n"; // Café simple, con leche, con azúcar - 8