제이온

[Effectieve Java] Item 5. Gebruik dependency injection in plaats van resources expliciet te noemen

Aangemaakt: 2024-04-28

Aangemaakt: 2024-04-28 13:39

Als een klasse intern afhankelijk is van een of meer resources en die resources van invloed zijn op het gedrag van de klasse, is het raadzaam om geen gebruik te maken van singletons en statische utility-klassen.


De klasse mag deze resources niet zelf aanmaken. In plaats daarvan is het wenselijk om de benodigde resources door te geven via de constructor. Door middel van dependency injection (afhankelijkheidsinjectie) kan de flexibiliteit, herbruikbaarheid en testbaarheid van de klasse worden verbeterd.


Voorbeeld

Voorbeeld van het gebruik van een statische utility-klasse

Deze utility-klasse gaat ervan uit dat er maar één woordenboek wordt gebruikt. In de praktijk is het echter zo dat er vaak aparte woordenboeken zijn voor verschillende talen, en soms zelfs aparte woordenboeken voor gespecialiseerde terminologie.


Voorbeeld van het gebruik van een singleton-klasse


Ook de singleton-klasse gaat ervan uit dat er maar één woordenboek wordt gebruikt, waardoor dezelfde nadelen optreden als hierboven beschreven.


Oplossing 1 - Het final-trefwoord uit het veld verwijderen.


Bij statische utility-klassen of singleton-klassen kan het final-trefwoord uit het dictionary-veld worden verwijderd en kan de klasse zo worden ontworpen dat het dictionary van buitenaf kan worden vervangen. Deze aanpak is echter onhandig in gebruik en kan in een multithread-omgeving leiden tot concurrency-problemen.


Oplossing 2 - Dependency Injection gebruiken.


Aan de hand van het bovenstaande voorbeeld is te zien dat statische klassen en singleton-klassen niet intern afhankelijk mogen zijn van resources. Met andere woorden, het is wenselijk dat interne resources van buitenaf worden geïnjecteerd.


Een klasse die gebruikmaakt van dependency injection, garandeert dankzij het final-trefwoord onveranderlijkheid en biedt de mogelijkheid om meerdere resource-instanties te ondersteunen. Dependency injection kan niet alleen worden toegepast via de constructor, maar ook via statische fabrieken en builders.


Bij dependency injection kan niet alleen de resource zelf worden doorgegeven, maar ook een resource-factory. Een factory is een object dat bij elke aanroep een instantie van een bepaald type aanmaakt. Deze aanpak staat bekend als het Factory Method-patroon en Supplier<T> in Java 8 is een perfect voorbeeld van een factory.



Meestal wordt een beperkte wildcard-type gebruikt om de typeparameter van de factory te beperken. Op deze manier kan de client elke factory doorgeven die een subtype is van het door hem opgegeven type.


Dependency injection verbetert de flexibiliteit en testbaarheid, maar kan bij projecten met veel afhankelijkheden behoorlijk kostbaar zijn. In dergelijke gevallen kunnen dependency injection frameworks (zoals Dagger, Guice en Spring) worden gebruikt om de kosten te verlagen.


Bron

Reacties0