Middle
Comment fonctionne un décorateur en PHP?
sobes.tech IA
Réponse de l'IA
Le motif "Décorateur" ajoute dynamiquement un nouveau comportement à un objet existant en l'enveloppant dans un autre objet appelé décorateur.
-
Composants :
- Interface (Component) : Déclare des méthodes communes pour l'objet d'origine et ses décorateurs.
- Composant Concret (Concrete Component) : Objet principal à décorer.
- Décorateur de Base (Decorator) : Classe abstraite ou interface contenant une référence à un objet de l'interface (Component) et implémentant ses méthodes, généralement en déléguant l'appel à cet objet.
- Décorateurs Concrets (Concrete Decorators) : Implémentent de nouvelles fonctionnalités, complétant ou modifiant le comportement du composant de base.
-
Principe de fonctionnement :
- Le décorateur contient une référence à l'objet qu'il décore (composition).
- Le décorateur a la même interface que l'objet décoré.
- Lorsqu'une méthode est appelée sur le décorateur, il effectue une logique supplémentaire avant ou après l'appel de la méthode correspondante sur l'objet décoré, ou le remplace complètement (bien que cela ne soit pas une utilisation typique).
-
Avantages :
- Permet d'ajouter des fonctionnalités aux objets au moment de l'exécution, et non de manière statique par héritage.
- Évite l'"explosion" de la hiérarchie de classes lors de la combinaison de plusieurs comportements différents.
- Permet de créer des combinaisons de comportements flexibles.
-
Exemple :
<?php
// Interface du composant
interface Coffee {
public function getCost(): float;
public function getDescription(): string;
}
// Composant concret
class SimpleCoffee implements Coffee {
public function getCost(): float {
return 5.0;
}
public function getDescription(): string {
return "Café simple";
}
}
// Décorateur de 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();
}
}
// Décorateur concret : Ajout de lait
class MilkDecorator extends CoffeeDecorator {
public function getCost(): float {
return parent::getCost() + 2.0;
}
public function getDescription(): string {
return parent::getDescription() . ", avec du lait";
}
}
// Décorateur concret : Ajout de sucre
class SugarDecorator extends CoffeeDecorator {
public function getCost(): float {
return parent::getCost() + 1.0;
}
public function getDescription(): string {
return parent::getDescription() . ", avec du sucre";
}
}
// Utilisation :
// Création d'un café simple
$coffee = new SimpleCoffee();
echo $coffee->getDescription() . " - " . $coffee->getCost() . "\n"; // Café simple - 5
// Ajout de lait
$coffeeWithMilk = new MilkDecorator($coffee);
echo $coffeeWithMilk->getDescription() . " - " . $coffeeWithMilk->getCost() . "\n"; // Café simple, avec du lait - 7
// Ajout de sucre
$coffeeWithMilkAndSugar = new SugarDecorator($coffeeWithMilk);
echo $coffeeWithMilkAndSugar->getDescription() . " - " . $coffeeWithMilkAndSugar->getCost() . "\n"; // Café simple, avec du lait, avec du sucre - 8