![translation](https://cdn.durumis.com/common/trans.png)
Ceci est un post traduit par IA.
[Effective Java] Item 5. Utilisez l'injection de dépendances au lieu de spécifier les ressources
- Langue de rédaction : Coréen
- •
-
Pays de référence : Tous les pays
- •
- Technologies de l'information
Choisir la langue
Texte résumé par l'IA durumis
- Si une classe dépend intérieurement d'une ou plusieurs ressources, il est préférable d'éviter d'utiliser les classes utilitaires statiques et les classes singletons, et d'utiliser plutôt l'injection de dépendances.
- L'utilisation de l'injection de dépendances peut améliorer la flexibilité, la réutilisabilité et la testabilité de la classe, et les ressources peuvent être injectées via le constructeur, l'usine statique, le générateur, etc.
- L'injection de dépendances peut être utilisée en passant la ressource elle-même ou l'usine de ressources, et dans les projets à forte dépendance, il est efficace d'utiliser un framework d'injection de dépendances.
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
public class SpellChecker {
private static final Lexicon dictionary = new Lexicon();
private SpellChecker() {
}
public static boolean isValid(String word) {
// Logique utilisant le dictionnaire
}
public static List suggestions(String typo) {
// Logique utilisant le dictionnaire
}
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
public class SpellChecker {
private final Lexicon dictionary = new Lexicon();
public static SpellChecker INSTANCE = new SpellChecker();
private SpellChecker() {
}
public static boolean isValid(String word) {
// Logique utilisant le dictionnaire
}
public static List suggestions(String typo) {
// Logique utilisant le dictionnaire
}
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
public class SpellChecker {
private Lexicon dictionary = new Lexicon();
public static SpellChecker INSTANCE = new SpellChecker();
private SpellChecker() {
}
public static void changeDictionary(Lexicon dictionary) {
this.dictionary = dictionary;
}
public static boolean isValid(String word) {
// Logique utilisant le dictionnaire
}
public static List suggestions(String typo) {
// Logique utilisant le dictionnaire
}
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
public class SpellChecker {
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary) {
this.dictionary = dictionary;
}
public static boolean isValid(String word) {
// Logique utilisant le dictionnaire
}
public static List suggestions(String typo) {
// Logique utilisant le dictionnaire
}
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
public static List create(Supplier extends Car> generator) {
...
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.