Habilitar las implementaciones de conmutación rápidamente (DbLogger en lugar de ConsoleLogger, por ejemplo)
Si bien la DI en general es seguramente algo bueno, sugeriría no usarla a ciegas para todo. Por ejemplo, nunca inyecto registradores. Una de las ventajas de DI es hacer que las dependencias sean explícitas y claras. No tiene sentido enumerar ILogger
como dependencia de casi todas las clases, es simplemente desorden. Es responsabilidad del registrador proporcionar la flexibilidad que necesita. Todos mis registradores son miembros finales estáticos, puedo considerar inyectar un registrador cuando necesito uno no estático.
Mayor número de clases.
Esta es una desventaja del marco DI o marco burlón dado, no del DI en sí. En la mayoría de los lugares, mis clases dependen de clases concretas, lo que significa que no se necesita cero repetitivo. Guice (un marco Java DI) enlaza por defecto una clase a sí mismo y solo necesito anular el enlace en las pruebas (o conectarlas manualmente en su lugar).
Creación de interfaces innecesarias.
Solo creo las interfaces cuando es necesario (lo cual es bastante raro). Esto significa que a veces, tengo que reemplazar todas las ocurrencias de una clase por una interfaz, pero el IDE puede hacer esto por mí.
¿Deberíamos usar la inyección de dependencia cuando solo tenemos una implementación?
Sí, pero evite cualquier repetitivo adicional .
¿Deberíamos prohibir la creación de nuevos objetos, excepto los de lenguaje / marco?
No. Habrá muchas clases de valor (inmutable) y de datos (mutable), donde las instancias simplemente se crean y pasan y donde no tiene sentido inyectarlas, ya que nunca se almacenan en otro objeto (o solo en otro tales objetos).
Para ellos, es posible que deba inyectar una fábrica, pero la mayoría de las veces no tiene sentido (imagine, por ejemplo, @Value class NamedUrl {private final String name; private final URL url;}
que realmente no necesita una fábrica aquí y no hay nada que inyectar).
¿Inyectar una sola implementación es una mala idea (digamos que tenemos solo una implementación, por lo que no queremos crear una interfaz "vacía") si no planeamos probar la unidad en una clase en particular?
En mi humilde opinión, está bien, siempre y cuando no causa la hinchazón de código. Inyecte la dependencia, pero no cree la interfaz (¡y sin XML de configuración loca!), Ya que puede hacerlo más tarde sin problemas.
En realidad, en mi proyecto actual, hay cuatro clases (de cientos), que decidí excluir de DI ya que son clases simples utilizadas en demasiados lugares, incluidos los objetos de datos.
Otra desventaja de la mayoría de los marcos DI es la sobrecarga de tiempo de ejecución. Esto se puede mover al tiempo de compilación (para Java, hay Dagger , no tengo idea de otros idiomas).
Otra desventaja es la magia que ocurre en todas partes, que se puede desactivar (por ejemplo, deshabilité la creación de proxy cuando uso Guice).
UserService
clase, esa es solo un titular de lógica. Se inyecta una conexión de base de datos y se ejecutan pruebas dentro de una transacción que se revierte. Muchos llamarían a esto una mala práctica, pero descubrí que esto funciona extremadamente bien. No necesita contorsionar su código solo para realizar pruebas y obtendrá el error de encontrar el poder de las pruebas de integración.