Pregunta

Puede alguien explicarme las ventajas de utilizar un contenedor de IOC simplemente codificar la implementación predeterminada en un constructor por defecto?

En otras palabras, lo que está mal en este código?

public class MyClass
{
    private IMyInterface _myInterface;

    public MyClass()
    {
        _myInterface = new DefaultMyInterface();
    }

    public MyClass(IMyInterface myInterface)
    {
        _myInterface = myInterface;
    }
}

Como lo que puedo decir, esta clase soporta inyección de constructor suficiente como para pruebas de unidad y de burla es fácil de hacer.Además, el constructor por defecto elimina la sobrecarga computacional del contenedor de IOC (por no hablar de todo el proceso es mucho más transparente).

Los únicos beneficios que puedo ver a la utilización de un contenedor de IOC es que si usted necesita para cambiar la aplicación de sus interfaces.Me estoy perdiendo algo?

¿Fue útil?

Solución

La idea de la Coi es delegar parte de su funcionalidad del componente a otra parte del sistema.En el mundial del Coi, tiene componentes que no saben el uno del otro.Su ejemplo viole esta, como la que está creando estrecho acoplamiento entre MyClass y algunos implementación de IMyInterface. La idea principal es que su componente no se tiene conocimiento sobre cómo va a ser utilizado.En su ejemplo, su componente hace algunos supuestos acerca de su uso.

En realidad, este enfoque puede funcionar, pero la mezcla de la Coi y explícita la inicialización del objeto no es una buena práctica de la OMI.

Coi le da un acoplamiento flexible mediante la realización de enlace en tiempo de ejecución por el precio de la claridad del código.Cuando un comportamiento adicional a este proceso, que hace las cosas aún más complicadas y pueden conducir a errores cuando algunos de los componentes potencialmente puede recibir objetos no deseados o imprevistos comportamiento.

Otros consejos

Escoge un lado :)

En resumen COI se recomienda.El problema con el código, es que no puedo cambiar la implementación predeterminada de la dependencia sin necesidad de recompilar el código que has dicho al final.COI le permite cambiar la configuración o composición de su objeto en un archivo externo sin necesidad de recompilación.
COI se apodera de la "construcción y montaje" la responsabilidad del resto del código. El propósito de la COI no es para hacer que tu código sea comprobable...es un agradable efecto secundario.(Como TDDed código conduce a un mejor diseño)

No hay nada de malo con este código y todavía se puede utilizar con la Inyección de Dependencia marcos como la Primavera y el Guice.

Muchos de los desarrolladores a la Primavera del archivo de configuración XML como una ventaja sobre el cableado de las dependencias dentro del código como puede cambiar las implementaciones sin necesidad de un paso de compilación.Este beneficio, en realidad se realiza en situaciones en la que ya tiene varias implementaciones compilado en su ruta de clase y desea elegir la aplicación en tiempo de implementación.Se puede imaginar una situación en la que un componente es proporcionado por un tercero después de la implementación.Del mismo modo no puede ser un caso cuando se desea realizar el envío adicional de implementaciones como un parche después de la implementación.

Pero no todos los marcos DI usar XML de configuración.Google Guice por ejemplo, los Módulos escritos como clases Java que debe ser compilado como cualquier otra clase de java.

Entonces, ¿cuál es la ventaja de DI si usted aún necesita un paso de compilación?Esto nos lleva de vuelta a tu pregunta original.Puedo ver siguientes ventajas:

  1. Un enfoque estándar para DI a lo largo de la aplicación.
  2. Configuración perfectamente separados a partir de otra lógica.
  3. Capacidad de inyectar proxies.La primavera, por ejemplo, permite el manejo de Transacciones declarativa mediante la inyección de servidores proxy en lugar de su aplicación
  4. Facilitar la reutilización de la lógica de configuración.Cuando utilice DI ampliamente, verá un complejo árbol de dependencias de la evolución a lo largo del tiempo.La gestión sin una claramente separados de configuración de la capa y el marco de apoyo puede ser una pesadilla.DI marcos hacen que sea fácil para volver a utilizar la lógica de configuración a través de la herencia y de otros medios.

La única preocupación que tengo es (1) si el servicio predeterminado de la dependencia de sí mismo tiene otro / secundaria dependencia de servicio (y así sucesivamente...su DefaultMyInterface depende de ILogger) y (2), es necesario aislar el primer servicio de dependencia a partir de la segunda (la necesidad de la prueba DefaultMyInterface con una punta de ILogger).En el caso de que usted, evidentemente, tendrá que perder el valor de "nueva DefaultMyInterface" y en lugar de hacer uno de los siguientes:(1) pura inyección de dependencia o (2) servicio de localizador o (3) el recipiente.Acumulación(nueva DefaultMyInterface());

Algunas de las preocupaciones de otros carteles que aparece puede no ser justo a su pregunta.Usted no estaban preguntando acerca de una multiplicidad de "producción" de las implementaciones.Usted está preguntando acerca de la la unidad de pruebas. En el caso de la unidad de tesing su enfoque, con mi primera advertencia declaró, parece legítimo;Yo también podría considerar su uso en simple unidad de casos de prueba.

Asimismo, un par de socorristas expresó su preocupación por repititiousness.No me gusta repitition, pero si (1) su implementación predeterminada es en realidad su defecto (YAGNI:usted no tiene planes de cambiar el valor predeterminado) y (2) usted no cree que la primera advertencia que me dijo se aplica y (3) prefieren el más simple código de enfoque que ha compartido, pues no creo que esta forma particular de repitition es un problema.

Además de acoplamiento flexible, un Coi va a reducir la duplicación de código.Cuando se utiliza un Coi y desea cambiar la implementación predeterminada de la interfaz, usted tiene que cambiar en un solo lugar.Cuando se utiliza de forma predeterminada contructors para inyectar la implementación predeterminada, usted tiene que cambiar en todas partes de la interfaz se utiliza.

En adición a los otros comentarios, uno podría argumentar que el SECO (No te repitas) principio en estos casos.Es redudnant a tener que aguantar que por defecto código de construcción en cada clase.También introducign caso especial de manejo de donde no hay no se necesita ninguna.

No veo por qué tu técnica de codificar la implementación predeterminada no podría ser utilizado junto con un contenedor de IOC.Simplemente, las dependencias no se especifica en la configuración tendría la implementación predeterminada.

O me estoy perdiendo algo?

Una de las razones que usted podría querer usar un Contenedor de IOC sería facilitar a finales de la configuración de su software.

Decir, por ejemplo, puede proporcionar varias implementaciones de una interfaz en particular - el cliente (o su equipo de servicios profesionales) puede decidir cual usar por la modificación de la COI archivo de configuración.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top