Si une classe dépend en interne d'une ou de plusieurs ressources, et que ces ressources affectent le fonctionnement de la classe, il est préférable de ne pas utiliser de singletons ni de classes utilitaires statiques.
Ces ressources ne doivent pas être créées directement par la classe, mais plutôt en les passant au constructeur. L'injection de dépendances permet d'améliorer la flexibilité, la réutilisabilité et la testabilité de la classe.
Exemple
Exemple d'utilisation d'une classe utilitaire statique
```javascript public class SpellChecker {
}
Cette classe utilitaire suppose qu'un seul dictionnaire est utilisé. Mais dans la réalité, il existe souvent des dictionnaires séparés par langue, et même des dictionnaires distincts pour les termes spécialisés.
Exemple d'utilisation d'une classe singleton
```javascript public class SpellChecker {
}
De même, une classe singleton suppose qu'un seul dictionnaire est utilisé, ce qui présente le même inconvénient que ci-dessus.
Solution 1 - Supprimer le mot-clé final du champ
```javascript public class SpellChecker {
}
Il est également possible de supprimer le mot-clé final du dictionnaire d'une classe utilitaire statique ou d'une classe singleton et de le remplacer par un autre dictionnaire à partir de l'extérieur. Cependant, cette approche est difficile à utiliser et peut poser des problèmes de concurrence dans un environnement multithreadé.
Solution 2 - Utiliser l'injection de dépendances
```javascript public class SpellChecker {
}
L'exemple ci-dessus montre que les classes statiques et les classes singleton ne doivent pas dépendre de ressources internes. En d'autres termes, les ressources internes doivent être injectées de l'extérieur.
Une classe utilisant l'injection de dépendances a l'avantage d'être immuable grâce au mot-clé final et de prendre en charge plusieurs instances de ressources. En outre, l'injection de dépendances peut être appliquée non seulement aux constructeurs, mais aussi aux méthodes d'usine statiques et aux constructeurs.
L'injection de dépendances consiste simplement à transmettre la ressource elle-même, mais il est souvent utilisé de transmettre une usine de ressources. Une usine est un objet qui crée à la demande des instances d'un type spécifique. Cette approche est appelée modèle de méthode d'usine et Supplier<T> en Java 8 est un exemple parfait d'une usine.
```javascript
public static List
Les génériques sont généralement utilisés pour limiter les paramètres de type de l'usine. Avec cette approche, le client peut transmettre n'importe quelle fabrique qui est un sous-type du type qu'il a spécifié.
L'injection de dépendances améliore la flexibilité et la testabilité, mais peut entraîner des coûts importants pour les projets ayant beaucoup de dépendances. Dans ce cas, vous pouvez utiliser un framework d'injection de dépendances (comme Dagger, Guice, Spring, etc.) pour réduire ces coûts.
Commentaires0