Nella programmazione ad oggetti, il decorator è uno dei pattern fondamentali, definiti originariamente dalla Gang of Four.
Il design pattern Decorator consente di aggiungere dinamicamente nuove funzionalità a oggetti già esistenti, senza modificarne la struttura. È particolarmente utile quando una determinata funzionalità aggiuntiva può essere applicata a diversi tipi di oggetti e può essere combinata con altre funzionalità in modo flessibile. Il Decorator consiste in una classe decoratore che "avvolge" l'oggetto originale (ricevuto come parametro dal costruttore). I decoratori possono inoltre decorarsi a vicenda. In questo modo, più decoratori possono essere concatenati l'uno all'altro, aggiungendo così in modo incrementale funzionalità alla classe concreta (che è rappresentata dall'ultimo anello della catena).
La concatenazione dei decoratori può avvenire secondo una composizione arbitraria: il numero di comportamenti possibili dell'oggetto composto varia dunque con legge combinatoriale rispetto al numero dei decoratori disponibili. Il decoratore implementa sempre la stessa interfaccia dell'oggetto che decora, e generalmente, una volta eseguita la propria parte di codice, delega le operazioni rimanenti all'oggetto decorato.
Questo pattern si pone come valida alternativa all'uso dell'ereditarietà singola o multipla, che richiederebbe di creare nuove classi per ciascuna combinazione di funzionalità richieste. Inoltre con l'ereditarietà, l'aggiunta di funzionalità avviene staticamente secondo i legami definiti nella gerarchia di classi e non è possibile ottenere al run-time una combinazione arbitraria delle funzionalità, tantomeno la loro aggiunta o rimozione. Per questo si favorisce la composizione di oggetti rispetto all'ereditarietà di classi.
Struttura di un decorator Component: definisce l'interfaccia dell'oggetto a cui verranno aggiunte nuove funzionalità. ConcreteComponent: definisce l'oggetto concreto al quale aggiungere le funzionalità. Decorator: mantiene un riferimento all'oggetto Component e definisce un'interfaccia conforme all'interfaccia Component. ConcreteDecorator: aggiunge le funzionalità al Component.
Funzionamento
Il Decorator manda le richieste al Component che può svolgere le operazioni precedenti e successive alla spedizione della richiesta.
In questo modo si ottiene una maggior flessibilità, tanti piccoli oggetti al posto di uno molto complicato, andando a modificare il contorno e non la sostanza di una classe.
Esempio
PHP abstract class Componente { protected $contenitore; protected $valore; abstract public function ottieniContenitore(); abstract public function ottieniValore(); }
class ComponenteConcreto extends Componente { public function __construct()
$this->valore = 1000; $this->contenitore = "Componente Concreto:\t{$this->valore}\n";
public function ottieniContenitore()
return $this->contenitore;
public function ottieniValore()
return $this->valore;
abstract class Decoratore extends Componente
class DecoratoreConcreto1 extends Decoratore { public function __construct(Componente $contenitore)
$this->valore = 1000; $this->contenitore = $contenitore;
public function ottieniContenitore()
return $this->contenitore->ottieniContenitore() . "Decoratore Concreto 1:\t{$this->valore}\n";
public function ottieniValore()
return $this->valore + $this->contenitore->ottieniValore();
class DecoratoreConcreto2 extends Decoratore { public function __construct(Componente $contenitore)
$this->valore = 1000; $this->contenitore = $contenitore;
public function ottieniContenitore()
return $this->contenitore->ottieniContenitore() . "Decoratore Concreto 2:\t{$this->valore}\n";
public function ottieniValore()
return $this->valore + $this->contenitore->ottieniValore();
class Cliente { private $componente;
public function __construct()
$this->componente = new ComponenteConcreto(); $this->componente = $this->avvolgiComponente($this->componente);
echo $this->componente->ottieniContenitore(); echo "Cliente:\t\t"; echo $this->componente->ottieniValore();
private function avvolgiComponente(Componente $componente)
$componente1 = new DecoratoreConcreto1($componente); $componente2 = new DecoratoreConcreto2($componente1); return $componente2;
echo "\n\n"; $cliente = new Cliente();
// Risultato: #quanton81
//Componente Concreto: 1000 //Decoratore Concreto 1: 1000 //Decoratore Concreto 2: 1000 //Cliente: 3000 Voci correlate Design patterns
Altri progetti
Categoria:Design pattern