Inyección de dependencias en Java

La evolución del acoplamiento arquitectónico

El diseño de software robusto busca reducir las dependencias fuertemente acopladas, esas donde los objetos instancian de forma interna y rígida a sus colaboradores.

  • Acoplamiento fuerte:
public class FacturacionService {
    // La clase instancia directamente una implementacion concreta, violando flexibilidad.
    private MySQLDatabase database = new MySQLDatabase(); 
}
  • Inyección por constructor (Inversión de Control pura):
public class FacturacionService {
    private final Database database;
    
    // La dependencia se suministra desde el exterior mediante polimorfismo e interfaces.
    public FacturacionService(Database database) {
        this.database = database;
    }
}

Comparativa de estrategias de inyección

  1. Constructor Injection (la más recomendada): Garantiza la inmutabilidad de los campos mediante el modificador final, asegura que el componente nace en un estado válido y operativo, y simplifica las pruebas unitarias sin necesidad de frameworks complejos.
  2. Setter Injection: Solo tiene sentido para dependencias opcionales o configuraciones mutables posteriores a la instanciación.
  3. Field Injection (@Autowired directo sobre atributos): Un mecanismo muy conciso, pero desaconsejado en producción: oculta las dependencias explícitas, dificulta crear instancias fuera del contenedor IoC y complica la ejecución de tests unitarios aislados.

IoC y el principio DIP

La Inversión de Control (IoC) transfiere la responsabilidad de crear objetos y gestionar su ciclo de vida desde el núcleo de la aplicación hacia un contenedor externo, algo que conecta directamente con el Principio de Inversión de Dependencias (DIP).

Preguntas clave

  1. ¿De qué manera concreta la inyección de dependencias ayuda a crear pruebas unitarias apoyándose en librerías de mocking como Mockito?
  2. ¿Qué problemas de arquitectura pueden surgir al abusar de contenedores IoC en aplicaciones monolíticas de gran escala?

© Arturo Juárez Monroy