Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

patrick246

Treue Seele

  • »patrick246« ist der Autor dieses Themas

Beiträge: 328

Wohnort: nahe Heilbronn/BW

Beruf: TG Profil Informatik-Schüler

  • Private Nachricht senden

1

22.02.2013, 21:49

Singleton gerechtfertigt?

Hallo,
da im Forum immer wieder gesagt wird, dass man Singletons nur dann verwenden soll, wenn es wirklich keine andere Instanz geben darf, frage ich vorher noch mal nach, ob das so gerechtfertigt ist :D

Es geht um einen Preloader für Waffendateien. Dieser speichert sie in einer map ab. Jetzt wäre ein 2. Objekt nicht so toll, da das dann auch nochmal die Waffen lädt und dadurch nochmal Speicher braucht. Zusätzlich wäre der Sinn des Preloadings verloren. Toller Nebeneffekt davon ist ja auch, dass ich darauf von überall zugreifen kann.

ProAmateur

Alter Hase

Beiträge: 434

Wohnort: Bei Simmern, Koblenz

Beruf: Schüler

  • Private Nachricht senden

2

22.02.2013, 21:55

Ja das würde mich auch mal interessieren, die selbe frage stelle ich für ein logfile.
Da wird ja oft davon abgeraten, dort singletons zu benutzen, aber eigentlich ist das da ja ein guter Einsatz.
"Die Neugier steht immer an erster Stelle eines Problems, das gelöst werden will."
Galileo Galilei
________________________________________________________________________

"Dumme Fragen gibt es nicht, dumm ist nur, wer nicht fragt.“

patrick246

Treue Seele

  • »patrick246« ist der Autor dieses Themas

Beiträge: 328

Wohnort: nahe Heilbronn/BW

Beruf: TG Profil Informatik-Schüler

  • Private Nachricht senden

3

22.02.2013, 21:59

Bei ner Logklasse würde ich das nicht verwenden, was spricht denn gegen mehrere Logfiles?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

22.02.2013, 22:17

Jetzt wäre ein 2. Objekt nicht so toll, da das dann auch nochmal die Waffen lädt und dadurch nochmal Speicher braucht.

Dann mach halt nur ein Objekt?

Toller Nebeneffekt davon ist ja auch, dass ich darauf von überall zugreifen kann.

Genau dieser "tolle Nebeneffekt" ist das Grundproblem von globalen Variablen und Singletons...

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »dot« (22.02.2013, 23:22)


Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

5

22.02.2013, 22:31

wenn es wirklich keine andere Instanz geben darf, [...] Jetzt wäre ein 2. Objekt nicht so toll


Merkst du was? ;)
Ein zweites Objekt ist kein Problem. Wenn das Universum auseinander fallen würde, wenn du ein 2. Objekt hättest, dann wäre auch die "darf" Bedinung erfüllt

patrick246

Treue Seele

  • »patrick246« ist der Autor dieses Themas

Beiträge: 328

Wohnort: nahe Heilbronn/BW

Beruf: TG Profil Informatik-Schüler

  • Private Nachricht senden

6

22.02.2013, 22:32

Also ich soll ein Objekt davon erstellen und dann immer durchreichen, bis es mal an ein Objekt kommt, wo es gebraucht wird?

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

7

22.02.2013, 23:09

Die Sache ist eigentlich relativ einfach. Singletons werden oft als Verschönerung von globalen Variablen verwendet. Das ist nicht besonders schön. Nun warum ist das so. Man kann sich gerne stundenlang über Codedesign streiten und was jetzt als schön und als unschön gilt. Das soll hier aber eigentlich auch gar nicht passieren wie ich finde. Was ist denn ein wirklicher Nachteil den man haben könnte, wenn man globale Variablen einsetzt. Im Prinzip nehme ich mir ja selbst Arbeit ab, indem ich die Objekte nun nicht immer durchreichen muss. Das hält meinen Code ein wenig schlanker und im Prinzip bleibt er doch übersichtlicher, wenn ich die Objekte nicht auch noch hin und her reichen muss.
Nun im Prinzip ist das erst mal richtig. Aber warum wird denn dann immer darauf geschimpft. Nun das Ding mit der Übersicht kann man auch umdrehen. Wenn ich viele globale Variablen habe, dann habe ich irgendwann weniger Übersicht, weil ich nicht mehr weiß was wo her kommt. Ich muss aufpassen was wo initialisiert wird und und und. Nun die Übersicht ist ein einzelner Punkt. Da kann man also sagen, man kann ein wenig abwägen, was nun übersichtlicher ist. Im Prinzip spricht dann ja immer noch nichts konkret gegen globale Variablen. Nun machen wir mal ein konkretes Beispiel. Du schreibst ein Spiel und möchtest die Spielerdaten global halten. So kannst du von überall darauf zugreifen. Schöne Sache erst mal. Jetzt möchtest du aber vielleicht einen zweiten Spieler anlegen. Jetzt musst du alle Daten kopieren und doppelt halten. Vielleicht möchtest du jetzt noch mehr Spieler zulassen. Spätestens da wünschst du dir, du hättest dich um eine vernünftige Verwaltung gekümmert. Das kann mit vielen anderen Dingen das selbe Problem sein. Anderes Beispiel mit selbem Problem. Du hast deinen Viewport global, damit du von überall darauf zugreifen kannst. Nun möchtest du einen Splitscreen haben. Brauchst also zwei Viewports. Selbes Problem wie oben. Wenn du deinen Klassen einfach den aktuellen Viewport übergeben würdest, oder den aktuellen Spieler, hättest du das Problem nicht gehabt. Nun ist die Lösung in diesen Fällen vernünftiges Codedesign. Das kostet nun mal Zeit und kann viel Arbeit sein. Dafür hast du Übersicht.
Man sollte selbst versuchen die Abhängigkeiten in Programmen möglichst klein zu halten. Warum möchtest du denn dass der Viewport global ist. Eigentlich nur damit du von überall darauf zugreifen kannst. Musst du das denn? Nein! Wenn du dir genau Gedanken darüber machst, wo deine Daten wirklich gebraucht werden, versuchst du automatisch Abhängigkeiten zu minimieren. Das sollte man zumindest versuchen;)
Als Anfänger ist das halt immer so eine Sache. Man kann das alles noch nicht so besonders gut einschätzen und vieles muss oft neu geschrieben werden. Und selbst bei Fortgeschrittenen und Profis ist das in vielen Fällen noch so. Da muss man lernen mit umzugehen.
Nicht nur Anfänger verwenden globals. Du solltest halt die Nachteile von globals kennen um abzuschätzen wie du damit umgehst. Guck doch vielleicht einfach mal bei Google nach den Nachteilen von globalen Variablen. Da findet man sicher ein paar Sachen. Versuch dann nachzuvollziehen was diese Nachteile genau bedeuten. Die Vorteile, bzw den Vorteil kennst du ja schon. Dann kannst du dir selbst überlegen ob und wann du denn globale Variablen einsetzen möchtest.
Wenn wir jetzt noch mal auf die Singletons zurück kommen. Nun im Prinzip benutzt man die, da man so den Vorteil von globalen Variablen hat und doch keine wirklichen globalen Variablen benutzen muss. Willst du globale Variablen benutzen, mach genau das. Wenn du jetzt noch mal auf das Einsatzgebiet von Singletons zurück kommst, dann siehst du, dass es darum geht, dass ein Objekt nur ein mal da sein darf. Das darf ist ein wichtiges Wort. Denk doch selbst mal über einen Fall nach bei dem das so ist. Nun nimmst du diesen Fall und denkst drüber nach was es bedeuten würde, wenn jetzt zwei Versionen davon da wären. Wäre das so schlimm? Vielleicht gibt es sogar ein Einsatzgebiet, bei welchem das so sein muss. Und genau das ist der Fall bei den meisten Einsatzgebieten von Singletons. Mit ein wenig Überlegung kommt man oft dazu, dass die Bedingung eigentlich nicht wirklich erfüllt ist. Es geht wie gesagt nicht darum, dass es doof wäre wenn das Objekt zwei mal da ist, sondern dass es wirklich Probleme machen würde. Nun da kann man jetzt wieder argumentieren, dass man das dann auch sicher anders und schöner ohne Singletons lösen kann. Aber hier ist es im Prinzip wieder das selbe wie bei so vielen Dingen. Überleg dir welche Vor- und Nachteile du aus etwas ziehen kannst. Und dann finde deinen Weg.
Bei vielen Dingen muss man auch einfach erst mal selbst auf die Schnauze fallen. Leute die irgendwas mal in nem Buch gelesen haben und dann predigen, dass ist der einzig wahre Weg, sind eigentlich recht merkwürdige Typen. Etwas muss sich ja erst mal durchsetzen. Manchmal kann man Argumenten von anderen folgen und sie nachvollziehen. Manchmal muss man aber einfach mal ein wenig rumprobieren, bis man es selbst merkt. Und wer etwas am eigenen Leib/Code erfahren musste, der weiß hinterher auch wirklich selbst wovon er redet.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

8

22.02.2013, 23:51

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. ;)
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

9

23.02.2013, 16:44

Dein Konzept spricht jetzt aber nicht direkt gegen Singletons. Du schreibst die Klassen sollen testbar sein. Ein Singleton kann man natürlich auch testen. Es verändert ein Objekt ja jetzt nicht so, dass es nicht mehr testbar ist. Da verstehe ich den Zusammenhang nicht ganz. Und auch für den Editor. Wenn das ganze über ein Singleton implementiert wäre, könnte man es dennoch austauschen. Das Singleton sagt ja erst mal nur, dass das Objekt nur ein mal da ist. Es sagt aber nicht, dass ein Singleton kein Interface implementieren kann, welches auch von einer anderen Klasse implementiert wird. Du kannst ein Singleton global beziehen, musst dies aber nicht tun. Von daher ist das eher wieder ein Punkt der gegen globale Variablen spricht, was hier ja am Ende mit reinkommt.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

10

23.02.2013, 17:30

Ich muss zugeben, dass sich mein Beitrag nicht auf Singletons an sich sondern auf deren häufigste Verwendungsart bezog: man hat eine Klasse mit privatem Konstruktor, die über eine statische Methode die einzige Instanz liefert, welche wiederum von überall aufgerufen wird (globale Variable). Würde man die einzige Instanz nicht von überall abrufen, sondern nur von einer Stelle aus und dann an alle benötigten Stellen weiterreichen, dann könnte man im Testfall auch ein anderes Objekt mit gleicher Schnittstelle/Basisklasse weiterreichen.
Und wenn man ohnehin schon dabei ist, die Instanz an alle benötigten Stellen weiter zu reichen, dann braucht man grundsätzlich kein Singleton mehr (würde ich zumindest frecherweise behaupten).

Vermutlich habe ich bisher einfach zu oft eine falsche Verwendung (global) von Singletons gesehen, wenn ich Singletons gesehen habe...
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Werbeanzeige