Which Of The Following Is Correct About Dependency Injection

La Inyección de Dependencias (ID) es un patrón de diseño fundamental en el desarrollo de software moderno. Su objetivo es reducir el acoplamiento entre clases. También mejorar la capacidad de prueba y la mantenibilidad del código.
¿Qué es la Inyección de Dependencias?
En esencia, la ID es una técnica donde las dependencias de una clase son inyectadas en ella, en lugar de que la clase las cree o las busque por sí misma. Una dependencia es cualquier objeto del que una clase necesita para funcionar correctamente. Piénsalo como los ingredientes que necesitas para cocinar una receta. En lugar de cultivar tus propios ingredientes, alguien te los proporciona.
Esto se logra típicamente a través de uno de tres mecanismos: inyección por constructor, inyección por setter e inyección por interfaz. Cada uno tiene sus ventajas y desventajas. La elección del mecanismo depende del contexto específico.
Must Read
Tipos de Inyección de Dependencias
Inyección por Constructor: La dependencia se pasa como argumento al constructor de la clase. Este es el método más común y recomendado. Asegura que la clase tenga todas sus dependencias desde el momento de su creación.
Ejemplo:
class Motor { ... }
class Coche {
private Motor motor;
public Coche(Motor motor) { this.motor = motor; }
}
Aquí, la clase `Coche` depende de la clase `Motor`. La instancia de `Motor` se inyecta a través del constructor de `Coche`.

Inyección por Setter: La dependencia se proporciona a través de un método setter público. Esto permite modificar la dependencia después de la creación del objeto, pero también puede dificultar la garantía de que la dependencia esté siempre presente.
Ejemplo:
class Logger { ... }
class Aplicacion {
private Logger logger;
public void setLogger(Logger logger) { this.logger = logger; }
}
En este caso, la clase `Aplicacion` puede recibir una instancia de `Logger` a través del método `setLogger`.

Inyección por Interfaz: La clase implementa una interfaz que define un método para recibir la dependencia. Esto es menos común, pero puede ser útil en escenarios específicos donde se necesita un alto grado de flexibilidad.
Ejemplo (simplificado):
interface LoggerAware {
void setLogger(Logger logger);
}
class Aplicacion implements LoggerAware {
private Logger logger;
public void setLogger(Logger logger) { this.logger = logger; }
}
La clase `Aplicacion` implementa la interfaz `LoggerAware`, que define el método `setLogger` para recibir la dependencia `Logger`.

Beneficios de la Inyección de Dependencias
La ID ofrece varios beneficios clave: * Bajo Acoplamiento: Las clases se vuelven menos dependientes de implementaciones concretas. Pueden trabajar con cualquier objeto que implemente la interfaz esperada. * Alta Cohesión: Las clases se enfocan en una sola tarea, lo que las hace más fáciles de entender y mantener. * Facilidad de Prueba: Es fácil reemplazar las dependencias reales con objetos mock durante las pruebas unitarias. Esto permite aislar y probar cada componente de forma independiente. * Reutilización de Código: Las clases se pueden reutilizar en diferentes contextos simplemente inyectando diferentes dependencias. * Mantenibilidad: Los cambios en una dependencia no afectan directamente a las clases que la utilizan, siempre y cuando la interfaz permanezca intacta.
Ejemplo Práctico
Imagina una aplicación que necesita enviar correos electrónicos. Sin ID, la clase que envía correos electrónicos podría estar directamente acoplada a una implementación específica de un servidor SMTP. Con ID, se define una interfaz `EmailService` y la clase que envía correos electrónicos depende de esta interfaz. Diferentes implementaciones de `EmailService` (por ejemplo, una para desarrollo que simplemente imprime el correo electrónico en la consola, y otra para producción que usa un servidor SMTP real) se pueden inyectar dependiendo del entorno.
En resumen, la Inyección de Dependencias es una técnica poderosa que promueve un código más flexible, mantenible y fácil de probar. Aunque puede parecer compleja al principio, los beneficios que ofrece la convierten en una práctica esencial para el desarrollo de software de calidad.
