Après les adapters nous allons parler d'un pattern similaire dans la conception, mais différent dans l'utilisation : Les décorateurs.

Comme le nom l'indique les décorateurs vont "décorer" un objet en y ajoutant des méthodes ou en modifiant le comportement de méthodes existantes. Prenons un exemple concret pour mieux comprendre le fonctionnement et l'utilité de ce pattern :

class Hello implements HelloInterface
{

    public function sayHello ($name) {
        return 'Bonjour ' . $name . '.'; 
    }

}

$hello = new Hello(); 
echo $hello->sayHello('Marc'); // Bonjour Marc.

Cette classe permet d'accueillir nos visiteurs en leur souhaitant la bienvenue. Mais maintenant on souhaite modifier le comportement de la classe suivant certains cas.

 class CaVaHelloDecorator implements HelloInterface{

    private $hello;

    public function __construct(HelloInterface $hello)
    {
        $this->hello = $hello;
    }

    public function sayHello ($name) {
        return $this->hello->sayHello($name) . ' Comment ça va ?';
    }

}

class BirthdayHelloDecorator implements HelloInterface{

    private $hello;

    public function __construct(HelloInterface $hello)
    {
        $this->hello = $hello;
    }

    public function sayHello ($name) {
        return $this->hello->sayHello($name) . ' Joyeux anniversaire !';
    }

}

Les décorateurs peuvent ensuite être utilisés pour greffer les comportements nécessaires suivant les cas.

$hello = new Hello(); 
$hello = new BirthdayHelloDecorator($hello); 
echo $hello->sayHello('Marc'); // Bonjour Marc. Joyeux anniversaire !'
$hello = new CaVaHelloDecorator($hello); 
echo $hello->sayHello('Marc'); // Bonjour Marc. Joyeux anniversaire ! Comment ça va ?'