Schorsch hat ja bereits einen sehr guten Beitrag geschrieben.
Ein anderer Punkt, warum ein Singleton schlecht sein kann: man kann ihn nicht "ersetzen". Ein Fall, der mich betreffen würde, wenn ich Singletons verwenden würde: ich will in Zukunft für mein Spiel einen Editor schreiben. Nun soll das Spiel in diesen Editor eingebettet sein und die Ressourcen vom Editor geliefert bekommen und nicht selbst aus dem Dateisystem auslesen. Würde ich einen Singleton verwenden, dann wäre eine mögliche Lösung vielleicht, dass der Singleton weiß, ob das Spiel im Editor ausgeführt wird oder alleinstehend. Allerdings will ich keinen Editor-Code im fertigen Spiel haben. Bisher habe ich dafür auch keinen Singleton verwendet, weshalb ich lediglich die Methoden der verwendeten Klasse in ein Interface auslagern müsste, die Klasse diese implementieren lassen (in dem Fall nur angeben, dass es implementiert wird, da die Implementierung bereits vorhanden ist), die Verweise auf die Klasse in Verweise auf das Interface umwandeln und schon könnte ich den Klassen, die darauf zugreifen bei der Ausführung im Editor ein ganz anderes Objekt mitgeben, welches sich ganz anders im Hintergrund verhält.
Und ein weiterer Punkt wäre es, die Klassen testbar zu halten, was wieder mit dem oberen Punkt zusammenhängt. Ich habe in meinem Spiel einen
VariablesManager, der die Spielinternen Variablen (nicht C#-Variablen) verwaltet. Dieser ist so aufgebaut, dass er vollkommen eigenständig und ohne Abhängigkeiten zu anderen Klassen funktioniert. Diese Klasse kann also vollständig auf Funktionstüchtigkeit getestet werden, ohne dass die Funktionstüchtigkeit anderer Einheiten darauf Einfluss haben. der
VariablesManager verwaltet die Variablen der Maps und die Variablen der Mapobjekte. Wenn nun das Verhalten eines Mapobjekts auf Korrektheit geprüft werden soll, könnte man meinen, dass dafür der
VariablesManager zwingend erforderlich sei. Da die Mapobjekte in meinem Fall aber kein Objekt dieser Klasse speichern, sondern nur Methoden mit den richtigen Parameterlisten und den richtigen Rückgabewerten, können auch ganz andere Methoden übergeben werden, die festgelegte Testdaten liefern und ihre Aufrufe protokollieren könnten. (Werden sie genau so aufgerufen, wie erwartet?) Wenn man für den DAtenzugriff einen Singleton hätte, der auf eine Datenbank oder das Dateisystem zugreifen würde, müsste man immer sicher gehen, dass auch die richtigen Testdaten vorliegen. Je nach Entwicklungsumgebung kann man diese Tests dann auch automatisiert durchlaufen lassen, damit man sich sicher sein kann, dass die getestete Funktionalität auch wirklich funktioniert. Das richtige Zusammenspiel ist dadurch zwar nicht gesichert, allerdings sind potenzielle Fehlerquellen eingeschränkt und man sieht, wenn Änderungen, die eigentlich die Funktionalität nicht zerstören sollten, die Funktionalität zerstören.
Allerdings solltest du das von mir geschriebene nur als eine Empfehlung ansehen, nicht als eine Aufforderung oder eine Anweisung. Ich versuche zwar, an möglichst jeder Stelle mit Tests vorzugehen, allerdings mache auch ich das nicht unbedingt überall.
Ich denke nicht, dass dich jemand köpfen wird, wenn du erstmal versuchst, Singletons zu verwenden. Wenn du für dich feststellen solltest, dass du keine Singletons (zumindest in diesem Fall) verwenden solltest, dann wäre das besser, als wenn du einfach keine Singletons verwendest, weil es dir gesagt wurde. Auch wenn man nicht unbedingt von Fehlern sprechen kann, aber dennoch halte ich den Spruch "Aus Fehlern lernt man." für angebracht. Auch ich habe schon viele "Fehler" gemacht und mache diese immernoch.