![translation](https://cdn.durumis.com/common/trans.png)
Esta es una publicación traducida por IA.
[Effective Java] Item 5. Utilice la inyección de dependencia en lugar de especificar recursos
- Idioma de escritura: Coreano
- •
-
País de referencia: Todos los países
- •
- Tecnología de la información
Seleccionar idioma
Texto resumido por la IA durumis
- Si una clase depende internamente de uno o más recursos, es mejor no usar clases de utilidad estáticas ni singletons, y es preferible usar la inyección de dependencia.
- El uso de la inyección de dependencia puede mejorar la flexibilidad, la reutilización y la facilidad de prueba de la clase, y los recursos pueden inyectarse en el constructor, la fábrica estática, el constructor, etc.
- La inyección de dependencia se puede usar pasando el propio recurso o una fábrica de recursos, y en proyectos con muchas dependencias, es eficiente usar un marco de inyección de dependencia.
Si una clase internamente depende de uno o más recursos, y esos recursos afectan el funcionamiento de la clase, es mejor no usar singletons o clases de utilidad estáticas.
La clase tampoco debe crear estos recursos directamente, sino que es mejor pasar los recursos necesarios al constructor. A través de la inyección de dependencia, se puede mejorar la flexibilidad, la reutilización y la facilidad de prueba de la clase.
Ejemplo
Ejemplo de uso de la clase de utilidad estática
public class SpellChecker {
private static final Lexicon dictionary = new Lexicon();
private SpellChecker() {
}
public static boolean isValid(String word) {
// Lógica que usa dictionary
}
public static List suggestions(String typo) {
// Lógica que usa dictionary
}
Se supone que esta clase de utilidad usa solo un diccionario. Sin embargo, en la realidad, los diccionarios están separados por idioma, e incluso hay diccionarios especiales para vocabulario especializado.
Ejemplo de uso de una clase singleton
public class SpellChecker {
private final Lexicon dictionary = new Lexicon();
public static SpellChecker INSTANCE = new SpellChecker();
private SpellChecker() {
}
public static boolean isValid(String word) {
// Lógica que usa dictionary
}
public static List suggestions(String typo) {
// Lógica que usa dictionary
}
De manera similar, la clase singleton también asume que usa solo un diccionario, por lo que ocurre la misma desventaja que antes.
Solución 1: Eliminar la palabra clave final del campo.
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) {
// Lógica que usa dictionary
}
public static List suggestions(String typo) {
// Lógica que usa dictionary
}
También puedes eliminar la palabra clave final del diccionario de la clase de utilidad estática o la clase singleton, y diseñar la clase para que se pueda reemplazar el diccionario con otro diccionario externo. Sin embargo, este método es difícil de usar en sí mismo, y puede causar problemas de simultaneidad en entornos multihilo.
Solución 2: Usar la inyección de dependencia.
public class SpellChecker {
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary) {
this.dictionary = dictionary;
}
public static boolean isValid(String word) {
// Lógica que usa dictionary
}
public static List suggestions(String typo) {
// Lógica que usa dictionary
}
A través del ejemplo anterior, podemos sentir que las clases estáticas y las clases singleton no deberían depender de recursos internos. Es decir, es mejor que los recursos internos se inyecten desde el exterior.
La clase que utiliza la inyección de dependencia tiene la ventaja de garantizar la inmutabilidad gracias a la palabra clave final, y admite múltiples instancias de recursos. Además, la inyección de dependencia se puede aplicar no solo en el constructor, sino también en fábricas estáticas y constructores.
La inyección de dependencia no solo se puede hacer pasando los recursos en sí, sino que también se usa a menudo pasando una fábrica de recursos. Una fábrica es un objeto que crea repetidamente instancias de un tipo específico cada vez que se llama. Este método se llama patrón de método de fábrica, y Supplier
public static List create(Supplier extends Car> generator) {
...
Principalmente, se utiliza un tipo de comodín limitado para restringir el parámetro de tipo de la fábrica. Al usar este método, el cliente puede pasar cualquier fábrica que sea un subtipo del tipo especificado.
La inyección de dependencia mejora la flexibilidad y la facilidad de prueba, pero puede ser bastante costosa en proyectos con muchas dependencias. En tales casos, puedes utilizar un marco de dependencia (Dagger, Guice, Spring, etc.) para reducir el costo.