2009-02-10 11 views
16

¿La inyección de dependencia significa que no necesita la palabra clave 'nueva'? ¿O es razonable crear directamente clases de hojas simples como colecciones?¿Hay algún caso de 'nuevo' cuando se usa la inyección de dependencia?

En el siguiente ejemplo me inyecto comparador, consulta y DAO, pero el SortedSet está directamente instanciado:

public Iterable<Employee> getRecentHires() 
{ 
    SortedSet<Employee> entries = new TreeSet<Employee>(comparator); 
    entries.addAll(employeeDao.findAll(query)); 
    return entries; 
} 

Respuesta

9

El hecho de que la inyección de dependencia es un patrón útil no significa que la usamos para todo. Incluso cuando se usa DI, a menudo habrá una necesidad de nuevo. No elimines lo nuevo por el momento.

0

Sí, por supuesto.

La inyección de dependencia se aplica a situaciones en las que podría haber varios objetivos de instanciación posibles de los cuales el cliente puede no estar al tanto (o no ser capaz de hacer una elección) del tiempo de compilación.

Sin embargo, hay suficientes situaciones en las que se sabe exactamente qué se quiere crear una instancia, por lo que no es necesario DI.

Esto es como invocar funciones en lenguajes orientados a objetos: simplemente porque puede usar encuadernación dinámica, no significa que no pueda usar un buen despacho estático (por ejemplo, cuando divide su método en varias operaciones privadas))

4

No hay nada de malo en usar nuevo como se muestra en su fragmento de código.

Considere el caso de querer agregar fragmentos de cadena. ¿Por qué querrías pedirle al inyector un StringBuilder?

En otra situación a la que me he enfrentado, necesitaba ejecutar un subproceso de acuerdo con el ciclo de vida de mi contenedor. En ese caso, tuve que hacer un nuevo Thread() porque mi Inyector se creó después de que se llamara el método de devolución de llamada para el inicio del contenedor. Y una vez que el inyector estaba listo, inyecté algunas clases administradas en mi subclase Thread.

6

Una forma en que normalmente decido si uso o no la inyección de dependencia es si necesito o no burlar o anular la clase colaboradora al escribir una prueba unitaria para la clase bajo prueba. Por ejemplo, en su ejemplo, usted (correctamente) está inyectando el DAO porque si escribe una prueba unitaria para su clase, probablemente no desee que se escriba ningún dato realmente en la base de datos. O tal vez una clase colaboradora escribe archivos en el sistema de archivos o depende de un recurso externo. O el comportamiento es impredecible o difícil de explicar en una prueba unitaria. En esos casos, es mejor inyectar esas dependencias.

Para las clases colaboradoras como TreeSet, normalmente no las inyectaría porque generalmente no hay necesidad de burlarse de clases simples como estas.

Una nota final: cuando un campo no puede ser inyectado por alguna razón, pero todavía me gustaría simularlo en una prueba, encontré la clase Junit-addons PrivateAccessor útil para poder cambiar el campo privado de la clase a un simulacro objeto creado por EasyMock (o jMock o cualquier otro marco de burla que prefiera).

+0

Spring también tiene la clase 'ReflectionTestUtils' para operaciones en miembros privados. –

0

Mi opinión es que DI es increíble y genial para conectar capas y también partes de tu código que deben ser flexibles para posibles cambios. Claro que podemos decir que todo puede necesitar cambios, pero todos sabemos que en la práctica algunas cosas simplemente no serán tocadas.

Así que cuando DI es excesivo, uso 'nuevo' y simplemente lo dejo rodar.

Ejemplo: para mí cablear un Modelo a la capa Vista para Controlador ... siempre se hace a través de DI. Algún algoritmo que utilicen mis aplicaciones, DI y también cualquier código reflectante conectable, DI. Capa de base de datos ... DI, pero prácticamente cualquier otro objeto que se use en mi sistema se maneja con un 'nuevo' común.

Espero que esto ayude.

0

Es cierto que en la actualidad, el entorno basado en el marco de trabajo instancia los objetos cada vez menos. Por ejemplo, los servlets se crean instancias mediante el contenedor de servlets, los beans en Spring crean una instancia con Spring, etc.

Aún así, al usar la capa de persistencia, creará instancias de sus objetos persistentes antes de que se hayan conservado. Al usar Hibernate, por ejemplo, llamará a nuevo en su objeto persistente antes de llamar a guardar en su HibernateTemplate.

Cuestiones relacionadas