Tra i design pattern più comuni in PHP e degni di nota troviamo sicuramente il Factory Pattern. Questo è un pattern creazionale, cioè un pattern che ci permette di creare un’istanza di una classe. Nel caso specifico, utilizzando il Factory attern, sarà possibile ottenere un oggetto senza conoscere l’esatta classe di provenienza.

In parole più semplici, quando instanziamo una classe in PHP generalmente facciamo:

$myObject = new MyClass();

Il Factory Pattern prevede la separazione tra la logica di creazione e l’effettiva logica di utilizzo di una classe. Supponiamo di avere una classe che rappresenta un concetto generico, ad esempio una classe “Toy”, giocattolo:

abstract class Toy 
{
    protected $price = 0;
    protected $code = '';
    public $name = '';
    
    public function __construct($code, $price) 

    public function prepare()
    {
        echo $this->name. ' is prepared';
    }

    public function package() 
    {
        echo $this->name. ' is packaged';
    }

    public function label()
    {
        echo $this->code . ' is priced at '.$this->price;
    }
}

Ora potremmo avere una serie di classi che estendono questa classe, modificandone il comportamento dei metodi o i valori degli attributi:

class CarToy extends Toy 
{
    public $name  = 'Car';
}

class HelicopterToy extends Toy 
{
    public $name  = 'Helicopter';
}

Bene, ora le classi CarToy e HelicopterToy ereditano i metodi della classe Toy e il costruttore che richiede il codice prodotto e un prezzo.

Per ottenere un oggetto di tipo HelicopterToy ora dovremmo fare una cosa del genere:

$helicopter = new HelicopterToy('AH0001', 99);

In questo modo avremo un’istanza della classe HelicopterToy con tutte le proprietà ereditate dalla classe Toy e delle proprietà definite al momento della generazione dell’istanza.

Ora se vogliamo ottenere un unico metodo per ottenere un oggetto Toy definendone il tipo (Car o Helicopter) ecco che entra in gioco il Factory Pattern. Definiamo una classe ToyFactory, in cui definiamo una logica secondo cui restituiamo l’istanza di una o l’altra classe. Questa logica può variare a seconda dello scenario e dai casi di utilizzo. Nel nostro caso ci limiteremo a passare un argomento che definisce il tipo di giocattolo che vogliamo ottenere:

class ToyFactory()
{
    public static function getToy($type, $code, $price)
    {
        $toy = ucfirst($type) . 'Toy';

        if(class_exists($toy)) {
            return new $toy($code, $price);
        } else {
            throw new Exception("Invalid toy type given.");
        }
    }
}

Come accennato, questa logica può variare a seconda dei casi di utilizzo, potrebbe agire ad esempio in base a una variabile d’ambiente o ad altri agenti esterni.

Tornando al nostro esempio ecco come ottenere un’istanza della classe CarToy:

$ferrari = ToyFactory::getToy('car', 'F0002', 39);

L’oggetto $ferrari adesso avrà tutti i metodi definiti nella classe Toy e il suo attributo $name sarà ‘car’.

Scopri la nostra splendida offerta PHP, ti aspettiamo in Aula o da Remoto con il nostro corso PHP ad Oggetti Base.

Scopri anche tutte le nostre risorse FREE di PHP! Ricorda, prima di passare allo studio di un framework come Laravel è determinante possedere un’ottima preparazione di PHP ad Oggetti! Se invece stai cercando un percorso di formazione one to one personalizzato scrivici a   amministrazione@laramind.com e in un attimo saremo da te!