Middle
Como funciona um decorador em PHP?
sobes.tech IA
Resposta da IA
O padrão "Decorador" adiciona dinamicamente um novo comportamento a um objeto existente envolvendo-o em outro objeto, chamado decorador.
-
Componentes:
- Interface (Component): Declara métodos comuns para o objeto original e seus decoradores.
- Componente Concreto (Concrete Component): Objeto principal que se deseja decorar.
- Decorador Base (Decorator): Classe abstrata ou interface que contém uma referência a um objeto da interface (Component) e implementa seus métodos, geralmente delegando a chamada a esse objeto.
- Decoradores Concretos (Concrete Decorators): Implementam novas funcionalidades, complementando ou modificando o comportamento do componente base.
-
Princípio de funcionamento:
- O decorador contém uma referência ao objeto que decora (composição).
- O decorador tem a mesma interface que o objeto decorado.
- Ao chamar um método no decorador, este realiza lógica adicional antes ou depois de chamar o método correspondente no objeto decorado, ou o substitui completamente (embora isso não seja uma utilização típica).
-
Vantagens:
- Permite adicionar funcionalidades aos objetos em tempo de execução, e não de forma estática por herança.
- Evita a "explosão" da hierarquia de classes ao combinar múltiplos comportamentos diferentes.
- Permite criar combinações de comportamentos flexíveis.
-
Exemplo:
<?php
// Interface do 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é simples";
}
}
// 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: Adicionar leite
class MilkDecorator extends CoffeeDecorator {
public function getCost(): float {
return parent::getCost() + 2.0;
}
public function getDescription(): string {
return parent::getDescription() . ", com leite";
}
}
// Decorador concreto: Adicionar açúcar
class SugarDecorator extends CoffeeDecorator {
public function getCost(): float {
return parent::getCost() + 1.0;
}
public function getDescription(): string {
return parent::getDescription() . ", com açúcar";
}
}
// Uso:
// Criar um café simples
$coffee = new SimpleCoffee();
echo $coffee->getDescription() . " - " . $coffee->getCost() . "\n"; // Café simples - 5
// Adicionar leite
$coffeeWithMilk = new MilkDecorator($coffee);
echo $coffeeWithMilk->getDescription() . " - " . $coffeeWithMilk->getCost() . "\n"; // Café simples, com leite - 7
// Adicionar açúcar
$coffeeWithMilkAndSugar = new SugarDecorator($coffeeWithMilk);
echo $coffeeWithMilkAndSugar->getDescription() . " - " . $coffeeWithMilkAndSugar->getCost() . "\n"; // Café simples, com leite, com açúcar - 8