Il Decorator Design Pattern in PHP

Il Decorator Design Pattern è un pattern strutturale che permette di aggiungere nuove funzionalità a un oggetto esistente senza modificare il suo codice. Questo pattern è utile quando si desidera estendere la funzionalità di un oggetto in modo dinamico, permettendo così di evitare l’overloading del codice o l’uso di classi troppo complesse.

Invece di modificare il comportamento di una classe direttamente, il Decorator Pattern permette di “decorare” un oggetto con nuove responsabilità, creando una relazione di composizione tra oggetti, dove uno decoratore incapsula l’oggetto originario e ne estende le funzionalità.

Esempio di Implementazione in PHP

In questo esempio, implementeremo una classe base che rappresenta un oggetto semplice e successivamente aggiungeremo dei decoratori per estenderne le funzionalità.

Immaginiamo di avere una classe Pizza e di voler aggiungere vari ingredienti come decoratori (es. formaggio extra, pomodoro, ecc.).

1. Creazione dell’oggetto base

La classe base Pizza rappresenta un oggetto di base che può essere decorato da altri oggetti.


class Pizza {
    public function getDescription(): string {
        return "Pizza base";
    }

    public function cost(): float {
        return 5.00;
    }
}

2. Creazione del decoratore astratto

Il decoratore astratto estende la classe Pizza e rappresenta una base per i decoratori concreti. Ogni decoratore deve implementare i metodi getDescription e cost.


abstract class PizzaDecorator extends Pizza {
    protected $pizza;

    public function __construct(Pizza $pizza) {
        $this->pizza = $pizza;
    }

    abstract public function getDescription(): string;
    abstract public function cost(): float;
}

3. Creazione dei decoratori concreti

Ogni decoratore concreto aggiungerà una funzionalità specifica all’oggetto Pizza originale, come ad esempio aggiungere un ingrediente.


class CheeseDecorator extends PizzaDecorator {
    public function getDescription(): string {
        return $this->pizza->getDescription() . ", con formaggio extra";
    }

    public function cost(): float {
        return $this->pizza->cost() + 2.00;
    }
}

class TomatoDecorator extends PizzaDecorator {
    public function getDescription(): string {
        return $this->pizza->getDescription() . ", con pomodoro";
    }

    public function cost(): float {
        return $this->pizza->cost() + 1.50;
    }
}

4. Utilizzo dei decoratori

Ora possiamo combinare i vari decoratori per creare una pizza personalizzata, aggiungendo funzionalità all’oggetto Pizza originale in modo dinamico.


$pizza = new Pizza();
$pizzaConFormaggio = new CheeseDecorator($pizza);
$pizzaConPomodoro = new TomatoDecorator($pizzaConFormaggio);

echo $pizzaConPomodoro->getDescription();  // Output: Pizza base, con formaggio extra, con pomodoro
echo $pizzaConPomodoro->cost();  // Output: 8.50

Conclusioni

Il Decorator Pattern consente di aggiungere comportamenti o funzionalità a oggetti esistenti in modo flessibile e senza modificare la classe originale. Questo è particolarmente utile quando si vuole evitare una proliferazione di classi per combinare diverse funzionalità. In PHP, l’uso di decoratori consente di estendere facilmente un oggetto senza dover cambiare il suo codice, seguendo il principio di Open/Closed Principle della SOLID.

Riferimenti

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *