Menu
Coddy logo textTech

Dependency Injection

Fa parte della sezione Programmazione orientata agli oggetti del percorso PHP di Coddy. Lezione 57 di 91.

Nella lezione precedente, hai visto come la composizione consente a una Car di contenere un oggetto Engine. Ma creare dipendenze all'interno della classe presenta un problema: rende il codice rigido e difficile da testare. L'iniezione delle dipendenze risolve questo problema passando le dipendenze dall'esterno invece di crearle internamente.

Confronta questi due approcci:

<?php
// Senza DI - dipendenza creata internamente
class Car {
    private Engine $engine;
    
    public function __construct() {
        $this->engine = new Engine(); // Strettamente accoppiato
    }
}

// Con DI - dipendenza passata dall'esterno
class Car {
    public function __construct(private Engine $engine) {}
}

$engine = new Engine();
$car = new Car($engine); // Iniettato dall'esterno

Il secondo approccio è l'iniezione delle dipendenze. La Car non crea il proprio motore: ne riceve uno. Questo semplice cambiamento offre vantaggi notevoli: puoi passare diversi tipi di motore, sostituire le implementazioni per i test e rendere la classe più flessibile.

Per una flessibilità ancora maggiore, inietta interfacce invece di classi concrete:

<?php
interface EngineInterface {
    public function start(): string;
}

class Car {
    public function __construct(private EngineInterface $engine) {}
    
    public function start(): string {
        return $this->engine->start();
    }
}

Ora Car funziona con qualsiasi classe che implementi EngineInterface - un motore a benzina, un motore elettrico o un mock per i test. Questo disaccoppiamento è il motivo per cui l'iniezione delle dipendenze è fondamentale per scrivere applicazioni PHP manutenibili e testabili.

challenge icon

Sfida

Facile

Costruiamo un sistema di notifiche che dimostri la potenza dell'iniezione delle dipendenze. Invece di definire in modo rigido come vengono inviati i messaggi, creerai un sistema flessibile in cui è facile sostituire il metodo di invio.

Organizzerai il codice in quattro file:

  • MessageSenderInterface.php: Definisci un'interfaccia chiamata MessageSenderInterface con un unico metodo send(string $recipient, string $message): string. Questa interfaccia stabilisce il contratto che ogni mittente di messaggi deve rispettare.
  • EmailSender.php: Crea una classe EmailSender che implementa MessageSenderInterface. Includi il file dell'interfaccia. Il metodo send() deve restituire "Email to [recipient]: [message]".
  • NotificationService.php: Crea una classe NotificationService che riceve la propria dipendenza tramite il costruttore. Includi il file dell'interfaccia. La classe deve:
    • Accettare un MessageSenderInterface nel costruttore usando la promozione delle proprietà del costruttore
    • Avere un metodo notify(string $recipient, string $message) che delega al mittente iniettato e ne restituisce il risultato
    Nota come NotificationService dipenda dall'interfaccia, non da una classe concreta. Ciò significa che puoi iniettare qualsiasi mittente che implementi l'interfaccia senza modificare il servizio.
  • main.php: Includi i file EmailSender e NotificationService. Riceverai due input: un destinatario e un messaggio. Crea un EmailSender, iniettalo in un NotificationService, poi chiama notify() e stampa il risultato.

Questo schema mantiene flessibile il tuo NotificationService. Funziona con qualsiasi mittente tu inietti, che si tratti di email, SMS o qualcosa che non hai ancora creato. Il servizio non crea le proprie dipendenze: le riceve dall'esterno.

Provalo tu

<?php
require_once 'EmailSender.php';
require_once 'NotificationService.php';

// Leggi l'input
$recipient = trim(fgets(STDIN));
$message = trim(fgets(STDIN));

// TODO: Crea un'istanza di EmailSender
// TODO: Iniettala in un'istanza di NotificationService
// TODO: Chiama notify() e stampa il risultato

?>
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore PHP online