Service Locator es solo el menor de dos males, por así decirlo. El "menor" se reduce a estas cuatro diferencias ( al menos no puedo pensar en ninguna otra en este momento ):
Principio de responsabilidad única
Service Container no viola el principio de responsabilidad única como lo hace Singleton. Los singleton combinan la creación de objetos y la lógica empresarial, mientras que Service Container es estrictamente responsable de administrar los ciclos de vida de los objetos de su aplicación. En ese sentido, Service Container es mejor.
Acoplamiento
Los singletons generalmente están codificados en su aplicación debido a las llamadas a métodos estáticos, lo que conduce a dependencias estrechamente acopladas y difíciles de simular en su código. El SL, por otro lado, es solo una clase y se puede inyectar. Entonces, si bien todos sus clasificados dependerán de ello, al menos es una dependencia poco acoplada. Entonces, a menos que haya implementado ServiceLocator como un Singleton, eso es algo mejor y también más fácil de probar.
Sin embargo, todas las clases que usan ServiceLocator ahora dependerán del ServiceLocator, que también es una forma de acoplamiento. Esto se puede mitigar mediante el uso de una interfaz para ServiceLocator para que no esté vinculado a una implementación de ServiceLocator concreta, pero sus clases dependerán de la existencia de algún tipo de localizador, mientras que no usar un ServiceLocator aumenta la reutilización drásticamente.
Dependencias ocultas
Sin embargo, el problema de ocultar las dependencias sigue existiendo. Cuando simplemente inyecta el localizador a sus clases consumidoras, no conocerá ninguna dependencia. Pero a diferencia del Singleton, el SL normalmente instanciará todas las dependencias necesarias detrás de escena. Por lo tanto, cuando obtiene un Servicio, no termina como Misko Hevery en el ejemplo de CreditCard , por ejemplo , no tiene que crear una instancia de todas las dependencias de las dependencias a mano.
Obtener las dependencias desde el interior de la instancia también viola la Ley de Demeter , que establece que no debe indagar en los colaboradores. Una instancia solo debe hablar con sus colaboradores inmediatos. Este es un problema tanto con Singleton como con ServiceLocator.
Estado global
El problema del estado global también se mitiga un poco porque cuando crea una instancia de un nuevo localizador de servicios entre pruebas, también se eliminan todas las instancias creadas anteriormente (a menos que haya cometido el error y las haya guardado en atributos estáticos en el SL). Eso no es cierto para ningún estado global en las clases administradas por el SL, por supuesto.
También vea Fowler en Service Locator vs Dependency Injection para una discusión mucho más profunda.
Una nota sobre su actualización y el artículo vinculado de Sebastian Bergmann sobre el código de prueba que usa Singletons : Sebastian, de ninguna manera, sugiere que la solución propuesta hace que el uso de Singleons sea menos problemático. Es solo una forma de hacer código que de otra manera sería imposible probar más comprobable. Pero sigue siendo un código problemático. De hecho, señala explícitamente: "El hecho de que puedas, no significa que debas".