Entiendo los beneficios de la inyección de dependencia en sí. Tomemos Spring, por ejemplo. También entiendo los beneficios de otras características de Spring como AOP, ayudantes de diferentes tipos, etc. Me pregunto cuáles son los beneficios de la configuración XML como:
<bean id="Mary" class="foo.bar.Female">
<property name="age" value="23"/>
</bean>
<bean id="John" class="foo.bar.Male">
<property name="girlfriend" ref="Mary"/>
</bean>
en comparación con el antiguo código Java simple, como:
Female mary = new Female();
mary.setAge(23);
Male john = new Male();
john.setGirlfriend(mary);
que es más fácil de depurar, se comprueba el tiempo de compilación y puede ser entendido por cualquiera que sólo conozca Java. Entonces, ¿cuál es el propósito principal de un marco de inyección de dependencia? (o un fragmento de código que muestre sus beneficios).
ACTUALIZACIÓN:
En caso de
IService myService;// ...
public void doSomething() {
myService.fetchData();
}
¿Cómo puede el marco de IoC adivinar qué implementación de myService quiero inyectar si hay más de una? Si solo hay una implementación de la interfaz dada, y dejo que el contenedor de IoC decida usarla automáticamente, se romperá después de que aparezca una segunda implementación. Y si intencionalmente solo hay una posible implementación de una interfaz, entonces no es necesario inyectarla.
Sería realmente interesante ver una pequeña parte de la configuración para IoC que muestra sus beneficios. He estado usando Spring por un tiempo y no puedo proporcionar tal ejemplo. Y puedo mostrar líneas simples que demuestran los beneficios de hibernate, dwr y otros marcos que uso.
ACTUALIZACIÓN 2:
Me doy cuenta de que la configuración de IoC se puede cambiar sin volver a compilar. ¿Es realmente tan buena idea? Puedo entender cuando alguien quiere cambiar las credenciales de la base de datos sin volver a compilar; puede que no sea un desarrollador. En su práctica, ¿con qué frecuencia alguien más que no sea el desarrollador cambia la configuración de IoC? Creo que para los desarrolladores no hay ningún esfuerzo por recompilar esa clase en particular en lugar de cambiar la configuración. Y para los que no son desarrolladores, probablemente querrá facilitarles la vida y proporcionar un archivo de configuración más simple.
ACTUALIZACIÓN 3:
Configuración externa de mapeo entre interfaces y sus implementaciones concretas
¿Qué tiene de bueno hacerla extenuante? No hace que todo su código sea externo, aunque definitivamente puede hacerlo, solo colóquelo en el archivo ClassName.java.txt, lea y compile manualmente sobre la marcha, wow, evitó volver a compilar. ¿Por qué debería evitarse la compilación?
Ahorra tiempo de codificación porque proporciona asignaciones de forma declarativa, no en un código de procedimiento
Entiendo que a veces el enfoque declarativo ahorra tiempo. Por ejemplo, declaro solo una vez un mapeo entre una propiedad de bean y una columna de base de datos e hibernate usa este mapeo mientras carga, guarda, construye SQL basado en HSQL, etc. Aquí es donde funciona el enfoque declarativo. En el caso de Spring (en mi ejemplo), la declaración tenía más líneas y tenía la misma expresividad que el código correspondiente. Si hay un ejemplo en el que dicha declaración es más corta que el código, me gustaría verlo.
El principio de inversión de control permite una prueba unitaria sencilla porque puede reemplazar implementaciones reales con falsas (como reemplazar la base de datos SQL por una en memoria)
Entiendo los beneficios de la inversión de control (prefiero llamar al patrón de diseño discutido aquí como Inyección de Dependencia, porque IoC es más general; hay muchos tipos de control y solo estamos invirtiendo uno de ellos: el control de inicialización). Estaba preguntando por qué alguien necesita algo más que un lenguaje de programación para ello. Definitivamente puedo reemplazar implementaciones reales con falsas usando código. Y este código expresará lo mismo que la configuración: solo inicializará campos con valores falsos.
mary = new FakeFemale();
Entiendo los beneficios de DI. No entiendo qué beneficios agrega la configuración XML externa en comparación con la configuración de código que hace lo mismo. No creo que deba evitarse la compilación; compilo todos los días y sigo vivo. Creo que la configuración de DI es un mal ejemplo de enfoque declarativo. La declaración puede ser útil si se declara una vez Y se usa muchas veces de diferentes maneras, como hibernate cfg, donde el mapeo entre la propiedad del bean y la columna DB se usa para guardar, cargar, construir consultas de búsqueda, etc. La configuración de Spring DI se puede traducir fácilmente a configurando el código, como al principio de esta pregunta, ¿no es así? Y se usa solo para la inicialización del bean, ¿no es así? Lo que significa que un enfoque declarativo no agrega nada aquí, ¿verdad?
Cuando declaro el mapeo de hibernación, solo le doy a hibernación algo de información, y funciona en función de ella, no le digo qué hacer. En caso de primavera, mi declaración le dice a la primavera exactamente qué hacer, entonces, ¿por qué declararlo, por qué no simplemente hacerlo?
ÚLTIMA ACTUALIZACIÓN:
Chicos, muchas respuestas me dicen sobre la inyección de dependencia, lo cual SÉ QUE ES BUENO. La pregunta es sobre el propósito de la configuración DI en lugar de inicializar el código; tiendo a pensar que la inicialización del código es más corta y clara. La única respuesta que he obtenido hasta ahora a mi pregunta es que evita la recompilación cuando cambia la configuración. Supongo que debería publicar otra pregunta, porque es un gran secreto para mí, por qué debería evitarse la compilación en este caso.