Service Locator ist sozusagen nur das kleinere von zwei Übeln. Das "Geringere", das auf diese vier Unterschiede hinausläuft ( zumindest kann ich mir momentan keine anderen vorstellen ):
Prinzip der Einzelverantwortung
Service Container verstößt nicht wie Singleton gegen das Prinzip der Einzelverantwortung. Singletons kombinieren Objekterstellung und Geschäftslogik, während der Service Container streng für die Verwaltung der Objektlebenszyklen Ihrer Anwendung verantwortlich ist. In dieser Hinsicht ist Service Container besser.
Kupplung
Singletons werden aufgrund der statischen Methodenaufrufe normalerweise fest in Ihre Anwendung codiert, was zu eng gekoppelten und schwer zu verspottenden Abhängigkeiten führt in Ihrem Code führt. Der SL hingegen ist nur eine Klasse und kann injiziert werden. Während also alle Ihre Klassen davon abhängen, handelt es sich zumindest um eine lose gekoppelte Abhängigkeit. Wenn Sie den ServiceLocator nicht als Singleton selbst implementiert haben, ist dies etwas besser und auch einfacher zu testen.
Alle Klassen, die den ServiceLocator verwenden, hängen jetzt jedoch vom ServiceLocator ab, der auch eine Form der Kopplung darstellt. Dies kann durch die Verwendung einer Schnittstelle für den ServiceLocator verringert werden, sodass Sie nicht an eine konkrete ServiceLocator-Implementierung gebunden sind. Ihre Klassen hängen jedoch von der Existenz eines Locators ab, während die Nichtverwendung eines ServiceLocator die Wiederverwendung erheblich erhöht.
Versteckte Abhängigkeiten
Das Problem, Abhängigkeiten zu verbergen, besteht jedoch sehr. Wenn Sie den Locator nur in Ihre konsumierenden Klassen einfügen, kennen Sie keine Abhängigkeiten. Im Gegensatz zum Singleton instanziiert der SL normalerweise alle Abhängigkeiten, die hinter den Kulissen benötigt werden. Wenn Sie also einen Service abrufen, werden Sie nicht so abrufen Misko Hevery im CreditCard-Beispiel enden , z. B. müssen Sie nicht alle Abhängigkeiten der Abhängigkeiten von Hand instanziieren.
Das Abrufen der Abhängigkeiten aus der Instanz heraus verletzt ebenfalls Demeter-Gesetz , das besagt, dass Sie sich nicht mit Mitarbeitern befassen sollten. Eine Instanz sollte nur mit ihren unmittelbaren Mitarbeitern sprechen. Dies ist sowohl bei Singleton als auch bei ServiceLocator ein Problem.
Globaler Staat
Das Problem des globalen Status wird auch etwas gemildert, da beim Instanziieren eines neuen Service Locator zwischen den Tests auch alle zuvor erstellten Instanzen gelöscht werden (es sei denn, Sie haben den Fehler gemacht und sie in statischen Attributen im SL gespeichert). Das gilt natürlich nicht für einen globalen Zustand in Klassen, die von der SL verwaltet werden.
Weitere Informationen finden Sie unter Fowler zu Service Locator und Abhängigkeitsinjektion .
Ein Hinweis zu Ihrem Update und der verlinkte Artikel von Sebastian Bergmann zum Testen von Code, der Singletons verwendet : Sebastian legt in keiner Weise nahe, dass die vorgeschlagene Problemumgehung die Verwendung von Singleons weniger problematisch macht. Es ist nur eine Möglichkeit, Code zu erstellen, der sonst nicht testbarer wäre. Aber es ist immer noch problematischer Code. In der Tat bemerkt er ausdrücklich: "Nur weil Sie können, heißt das nicht, dass Sie sollten".