Tengo una buena cantidad de OOP con varios idiomas, pero soy bastante nuevo en Java.
Estoy leyendo una gran cantidad de tutoriales donde se crean grandes cantidades de objetos dentro del código de una clase, y estoy tratando de ejecutarlos, pero construyo versiones de las clases en los tutoriales que hacen la Inyección de dependencia en lugar de instanciar todos los clases ellos mismos.
Pero Java no es como otros lenguajes que he usado en que casi todo es un objeto. Si tuviera que inyectar literalmente todo, entonces el resultado sería muy complicado y difícil de seguir.
Obviamente no inyectarías objetos String, y supongo que hay otros objetos que no inyectarías, pero no estoy seguro de dónde debe ir la línea. ¿En qué momento DI deja de ser lo correcto y cuándo comienza a ser una carga? ¿Cómo se decide pragmáticamente qué inyectar y qué crear una instancia?
Para su información, los tutoriales que estoy haciendo son http://edn.embarcadero.com/article/31995 y http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html para crear un cliente simple y servidor. Sin embargo, no los estoy copiando línea por línea, estoy tratando de crear clases equivalentes que sigan las mejores prácticas
Respuestas:
En .Net (que es similar a este respecto que todo es un objeto), utilizo DI principalmente con mis objetos de dominio (entidades, repositorios y servicios) y objetos de aplicación (controladores, modelos de vista), por lo que los repos / servicios se inyectan en el controlador / ver modelos y similares. Esto significa que mi lógica empresarial y de aplicación es totalmente comprobable, que es la razón principal por la que uso DI.
Básicamente, los objetos en los que se inyecta e inyecta material son en su mayoría objetos específicos de la solución que está creando. Si algún objeto es "nativo" del lenguaje o marco (como .Net), probablemente no sea necesario inyectarlo. Muchos objetos necesitan una cadena para representar datos, y una cadena es básicamente una "característica de lenguaje" que no es específica de su dominio. Lo mismo se aplica a los enumerables, las listas, las matrices y muchas otras cosas que no necesitan cambiar cuando desea ejecutar su clase de forma aislada del resto del sistema.
Lo más importante a tener en cuenta es el acoplamiento entre sus clases de dominio / aplicación. Si un objeto no introduce un acoplamiento apretado, generalmente es seguro crearlo. Una de las formas de verificar el acoplamiento es intentar ejecutar los métodos en una clase de forma aislada (que es básicamente una prueba unitaria). Lo que debe ser DI-ed son todas las dependencias de las que necesita burlarse, para asegurarse de que la clase que está probando realmente se ejecute aisladamente del sistema.
fuente
En primer lugar, está bien usar la nueva palabra clave, ¡de verdad! La DI es una técnica fantástica, pero existe la tentación de usarla en exceso. Los momentos en que es posible que desee utilizar DI son:
Dobles de prueba: a menudo, con las pruebas unitarias, desea simular / probar el doble de un recurso de terceros ya que no desea activar ese recurso de terceros (por ejemplo, una base de datos Oracle completa). Por ejemplo, en lugar de crear una nueva conexión de base de datos a la gran base de datos Oracle, es posible que desee reemplazar esa conexión con una a un HSQL (en la base de datos de memoria).
Cuando desea controlar el alcance (~ vida útil) de ese objeto y el ciclo de vida natural de los objetos Java no funciona para usted. Muchos frameworks DI basados en Java le permiten hacer esto.
Cuando quieres solteros.
Cada vez que crea que necesita una Fábrica, un Localizador de servicios o similar. Esto incluye si necesita diferentes fábricas (raro, pero sucede).
En otras ocasiones, simplemente cree un nuevo objeto, de hecho, si tiene dudas, cree un nuevo objeto; siempre puede DI cuando lo necesite más tarde :-).
fuente
De Wikipedia :
No debería necesitar inyectar cadenas, simplemente puede pasarlas como parámetros al método relevante. No debería necesitar inyectar ningún dato, aparte de config.
Las buenas pruebas de unidad lo ayudan a localizar errores y, por lo tanto, debe probar su código independientemente de otras unidades de código. DI puede ayudarlo a lograr esto.
fuente
En general, encuentro que una clase solo debería ser
new
de otra clase.Esto se debe a que una vez que va por el camino de la inyección de dependencias, cada objeto que usa
new
tiene que inyectar todas las dependencias de los objetos que crea, lo que significa que el objeto padre también debe conocer todas esas dependencias. SiA
tiene una dependenciaB
yC
creaA
instancias,new
entoncesC
automáticamente necesita tener una dependenciaB
, incluso siC
nunca se usaB
directamente. Primero, eso viola la separación de preocupaciones, a menos queC
el único trabajo sea crearA
s. De lo contrario, crea un problema si alguna vez desea agregar una dependenciaA
porque todas las cosas que la crean ahora necesitan agregar esa misma dependencia. Realmente no deberían preocuparse por eso. Es mejor tenerC
declarar una dependenciaAFactory
yAFactory
tener una dependencia enB
. Luego puede agregar dependencias aA
todo lo que desee, y soloAFactory
tiene que cambiar.fuente
"¿En qué momento DI deja de ser lo correcto y cuándo comienza a ser una carga? ..."
En primer lugar, me gusta la DI y la uso mucho, así que no me malinterpreten
DI es excelente para el lado del servidor, pero los juegos cambian todos juntos cuando se trata de programación Gui. Por ejemplo, incorporé Guice a una aplicación GUI existente desarrollada en Swing
¿Cómo manejar las dependencias anidadas?
supongamos que necesita acceder a algunas dependencias en clases profundamente anidadas, puede usar DI de una de las siguientes maneras:
¿Qué tal si desea crear un objeto usando new () (porque el objeto necesita ser creado en tiempo de ejecución dependiendo de algunos criterios) y desea registrarlo en el contenedor (Guice no maneja objetos creados con new (), que es bueno ) Por lo tanto, ahora debe volver a centrarse en el contenedor en lugar de desarrollar nuevas funciones en su aplicación.
Palabras finales en algunos casos usando DesignPatterns + pensamiento creativo y buen diseño de arquitectura, puede evitar situaciones donde la ganancia es pequeña y las molestias son altas como resultado de la introducción de DI
fuente