Die meisten wissen nicht, worum es eigentlich geht und wiederholen nur, was sie mal irgendwo gehört haben.
Das Problem bei global state (egal, ob einzelne globale Variablen oder ein fest verdrahtetes Singleton) ist, dass man eher schwerlich entkoppelt testen kann. Wenn Komponente/Klasse/Funktion X hartverdrahtet Y.Irgendwas referenziert, dann muss ich in einem Test immer dafür sorgen, dass Y.Irgendwas auch den richtigen wert für den Testvorgang enthält. Misko Hevery erklärt in seinem
Guide recht gut, warum sich daraus Probleme ergeben, sowohl technischer Natur als auch vom Verständnis her, wenn man sich die
API von X anschaut, welche möglicherweise nix über ihre "geheime" Interaktion mit Y sagt.
Zudem macht er einen Unterschied zwischen "Singleton" und der "singletoness" - beim Singleton, wie oft implementiert (je nach Sprache mehr oder minder einfach zu realisieren) geht es darum, komplett zu verhindern, dass jemand jemals eine andere Instanz als die einzig wahre erstellen kann (technische Limitierung). Bei der "singletoness" geht es darum, dass es von der Semantik der Anwendung nur eine Instanz gibt. Es steht aber nicht im Weg, zum Testen selbst eine Instanz davon zu erzeugen, um sie für den Test mit entsprechenden Daten zu versorgen, etc oder gar auszumocken.
Am Beispiel von TMessageManager erklärt: Wenn ich in meinem Code überall einfach TMessageManager.DefaultManager.SubscriptToMessage oder SendMessage aufrufe, dann habe ich mich an den Singleton gebunden. Nehme ich über den ctor oder eine Eigenschaft eine TMessageManager Instanz entgehen, mit der ich interagiere, dann habe ich diese Abhängigkeit entfernt bzw "aufgeweicht", denn ich kann von außen steuern, mit welcher TMessageManager Instanz die Komponente kommuniziert.