Sobes.tech
Middle

Qual è la differenza tra inversione del controllo (IoC) e iniezione delle dipendenze?

sobes.tech AI

Risposta dell'AI

L'inversione del controllo (IoC) è un principio di progettazione generale secondo cui il flusso di controllo di un programma cambia: invece di gestire esplicitamente le dipendenze e la logica delle loro chiamate, il componente si affida a un framework o contenitore esterno che gestisce questo flusso.

L'iniezione delle dipendenze (DI) è uno dei pattern specifici che implementano il principio IoC. Consiste nel passare le dipendenze (oggetti di cui dipende il componente corrente) al componente dall'esterno, invece che il componente le crei o le cerchi da solo.

Pertanto, DI è un modo per raggiungere IoC.

Le principali differenze:

  • IoC — principio/concezione.
  • DI — pattern/implementazione.
  • IoC può essere implementato in diversi modi (ad esempio, metodo factory, service locator), DI è uno di questi modi.
  • IoC sposta la responsabilità di creare e collegare gli oggetti da il componente a il framework o contenitore.
  • DI realizza questo spostamento passando le dipendenze tramite costruttore, setter o interfaccia.

Esempio di DI (costruttore):

// classe dipendente da Service
public class Client {
    private final Service service;

    // Il costruttore riceve la dipendenza (Service)
    public Client(Service service) {
        this.service = service;
    }

    public void doSomething() {
        service.execute();
    }
}

// Interfaccia di dipendenza
public interface Service {
    void execute();
}

// Implementazione concreta di dipendenza
public class ServiceImpl implements Service {
    @Override
    public void execute() {
        System.out.println("Esecuzione del servizio...");
    }
}

// Classe responsabile dell"iniezione"
public class AppConfig {
    public static void main(String[] args) {
        Service myService = new ServiceImpl(); // Creazione dipendenza
        Client client = new Client(myService); // Iniezione dipendenza tramite costruttore
        client.doSomething();
    }
}

In questo esempio, la classe Client non crea direttamente ServiceImpl. Invece, ServiceImpl viene creato altrove (AppConfig) e passato (iniettato) in Client tramite il suo costruttore. Questo implementa il principio IoC, poiché il controllo della creazione e del collegamento di Service è invertito — non è in Client.