제이온

[Effective Java] Item 5: Utilizza l'iniezione di dipendenze invece di specificare direttamente le risorse

Creato: 2024-04-28

Creato: 2024-04-28 13:39

Se una classe dipende internamente da una o più risorse e tali risorse influenzano il comportamento della classe, è consigliabile evitare di utilizzare classi singleton e classi di utilità statiche.


La classe non dovrebbe creare queste risorse direttamente, ma è preferibile passare le risorse necessarie al costruttore. L'iniezione di dipendenze può migliorare la flessibilità, la riusabilità e la facilità di test della classe.


Esempio

Esempio di utilizzo di una classe di utilità statica

Questa classe di utilità presuppone l'utilizzo di un solo dizionario. Tuttavia, nella realtà, i dizionari possono essere distinti per lingua e possono anche esistere dizionari separati per vocabolari specializzati.


Esempio di utilizzo di una classe singleton


Anche la classe singleton presuppone l'utilizzo di un solo dizionario, quindi presenta lo stesso svantaggio di cui sopra.


Soluzione 1 - Rimuovere la parola chiave final dal campo


È possibile rimuovere la parola chiave final dal campo dictionary di una classe di utilità statica o di una classe singleton e consentire l'aggiornamento del dizionario dall'esterno. Tuttavia, questo approccio è scomodo da utilizzare e può causare problemi di concorrenza in ambienti multithread.


Soluzione 2 - Utilizzare l'iniezione di dipendenze


Dall'esempio precedente, possiamo capire che le classi statiche e le classi singleton non dovrebbero dipendere da risorse interne. In altre parole, è preferibile che le risorse interne vengano iniettate dall'esterno.


Le classi che utilizzano l'iniezione di dipendenze possono garantire l'immutabilità grazie alla parola chiave final e supportano più istanze di risorse. Inoltre, l'iniezione di dipendenze può essere applicata non solo nei costruttori, ma anche nelle factory statiche e nei builder.


L'iniezione di dipendenze può semplicemente passare la risorsa stessa, ma spesso viene utilizzato anche un approccio in cui viene passata una factory di risorse. Una factory è un oggetto che crea ripetutamente istanze di un determinato tipo quando viene chiamato. Questo approccio è chiamato pattern Factory Method e Supplier<T> in Java 8 è un perfetto esempio di rappresentazione di una factory.



In genere, viene utilizzato un tipo di carattere jolly limitato per limitare il parametro di tipo della factory. In questo modo, il client può passare qualsiasi factory che sia un sottotipo del tipo specificato dal client.


Sebbene l'iniezione di dipendenze migliori la flessibilità e la facilità di test, può comportare costi elevati in progetti con molte dipendenze. In questi casi, è possibile ridurre i costi utilizzando un framework di iniezione di dipendenze (come Dagger, Guice o Spring).


Fonte

Commenti0