2011-06-09 18 views
5

estoy revisando código con una gran cantidad de declaraciones como esta:Servicio de localización frente a la inyección de dependencias

private SomeInterface x = Locator.getInstance(SomeInterface.class) 

yo esperaría algo así como

private SomeInterface x; 

@Inject 
public Consumer(SomeInterface x){ // constructor 
    this.x = x; 
} 

¿Hay algo malo con el primer enfoque? De acuerdo, las dependencias no son tan obvias, pero las implementaciones podrían intercambiarse fácilmente a través de la configuración de Locator.

+0

https://steveschols.wordpress.com/2012/05/14/dependency-injection-vs-service-locator/#comment-539 –

Respuesta

6

Primer ejemplo: x = Locator.getInstance (SomeInterface.class) es parece patrón Service Locator, y http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx verificación de este artículo que dice Locator Service es un anti-patrón y se debe evitar

Y para el el segundo uso es todo bien, me gusta la inyección de constructores, su implementación suave y precisa. Pero me gustaría no utilizar Atributos (annotanitons en Java?) Porque siempre que quiera cambiar el contenedor DI que estoy usando y no quiero eliminar un atributo de todas las clases.

+2

'@ Inject' está estandarizado en Java por [JSR-330] (http://www.jcp.org/en/jsr/detail?id=330) – deamon

+0

@deamon Pensé que era solo la anotación de DI de CrazyBob. No sabía que fue aceptado como idioma estándar. Gracias por la info. – adt

9

Martin Fowler escribió un article on DI versus Locators:

Por DI:

  • más fácil determinar lo que las dependencias de un componente haya - mira constructor.
  • El componente no tiene dependencia en el Localizador de servicios por lo que no hay un problema si el componente se usa con un marco diferente.
  • DI puede facilitar el control más fácil, pero un buen mecanismo de Servicio de localización se stubbing marca igualmente factible

contra el DI:

  • Más difícil de depurar y entender.
  • El componente no puede solicitar servicios adicionales desde el inyector una vez que se configuró .

Yo personalmente no creo que haya nada inherentemente malo con el enfoque basado primer localizador - supongo DI no estandarizar esto, sin embargo, por lo que si está disponible lo usaría. Todas las buenas ideas tienden a terminar como marcos en algún momento, así que esto tiene lo que sucedió aquí. Además con DI puede aprovechar otras anotaciones, ámbitos, etc. sin tener que rodar su propio código. Y el código menos personalizado de su proyecto utiliza la mejor IMO. Voy a dejar la última palabra a pesar de Fowler:

La elección entre Servicio de Localización y inyección de dependencia es menos importante que el principio de la separación de configuración servicio de la utilización de los servicios dentro de una aplicación.

1

hay nada "malo" como tal con el patrón de servicio de localización,

En este caso particular, el principal argumento a favor de la DI sería la capacidad de prueba.

Sin duda, DI permite una mejor prueba de la unidad. El método estático getInstance en Locator hace que sea más difícil de probar de forma aislada.

+0

Hay más que solo pruebas unitarias. Mark Seemann lo ha descrito muy claramente: http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx. – Steven

+2

Quería evitar este tipo de discusiones filosóficas :) "Anti-Pattern" es una declaración muy utilizada en mi humilde opinión. Personalmente, también estoy a favor de DI, pero no llegaría tan lejos como para marcarlo como un anti patrón durante una revisión del código. – ddewaele

+0

Presenté IoC (en forma de patrón de localizador de servicios) hace algunos años en un proyecto para permitir que ese equipo comenzara a escribir pruebas. Fue un buen comienzo al no poder probar en absoluto. Pero ahora, más de dos años después, tener este patrón por todos lados en lugar de usar DI es un verdadero dolor real. Entonces para mí ya no es filosófico. He estado allí, lo experimenté, y fue todo por mi culpa. Estos días trato de gritar tanto como puedo para ayudar a otros a cometer el error que cometí. – Steven

2

Service locator patrón utiliza un registro central conocido como el "localizador de servicios" que a petición devuelve la información necesaria para realizar una determinada tarea.

Estos son los peores lados del Servicio de Localización de patrones de diseño:

  • cosas que estén en el registro son cajas negras con eficacia lo que respecta al resto del sistema. Esto hace que sea más difícil detectar y recuperarse de sus errores, y puede hacer que el sistema como un todo sea menos confiable.

  • El registro debe ser único, lo que puede convertirse en un cuello de botella para las aplicaciones concurrentes
    .

  • El registro puede ser una vulnerabilidad de seguridad grave, porque permite a los intrusos a insertar código directamente en una aplicación.

  • no pueden pasar por las dependencias del constructor (como lo hacemos en el patrón DI) y duro a la unidad de prueba

Y mi opinión el uso de patrón de diseño del localizador servicio es aceptable sólo en el nivel superior de su aplicación cuando su localizador de servicios probablemente no cambie

Cuestiones relacionadas