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

1

04.09.2011, 11:20

Sinn von Singleton

Also ich hab mir den Singleton Text schon ein paar mal durchgelesen aber ich versteh noch nicht ganz was das Ding machen soll?
Geht es hier wirklich NUR um Logfiles?
Ausserdem ist immer nur die Rede von Klassen mit nur EINER Instanz, welche Klasse ist hier gemeint? Etwa die Singleton-Klasse selbst oder die Logfile-Instanz?
Und welchen Pointer, welcher Instanz gebe ich zurück? Nur den der Singleton-Instanz?

Ich rufe im main() die Get aus der Singleton auf (1 Instanz wird erzeugt) und da die Logfile diese geerbt hat, kann ich dann die Statusmeldung aufrufen. Welchen Sinn hat das alles?
Geht es hier nur darum, dass ich EIN MAL eine Singleton-Instanz erstelle und diese dann läuft? Was kann ich dann damit tun?

In der Singleton ist ja im Prinzip nur ein erstellen und zurückliefern der Instanz drin und einmal ein zerstören der Instanz und dann greife ich auf die Logfile zu. Ist das der Sinn des Ganzen?
„lean over the bowl and then take a dive all of you are dead. i am alive“

ridens

Frischling

Beiträge: 47

Beruf: Freiberuflicher Entwickler

  • Private Nachricht senden

2

04.09.2011, 11:51

Der Sinn von Singleton ist genau das, was es ja ist: eine Klasse, von der es nur eine globale Instanz gibt. Das Logfile ist nur ein Beispiel dafür. Ein anderes Beispiel wäre z.B. eine Klasse, die beim Erstellen der Instanz eine Verbindung zu einer Datenbank aufbaut und dann Funktionen bereitstellt, um dort Daten auszulesen oder hineinzuschreiben. Es wäre meist nicht sinnvoll, mehrere Verbindungen aufzubauen, darum baut man diese DB-Klasse als Singleton, damit nur eine Instanz und damit nur eine DB-Verbindung aufgebaut werden. Die Get-Funktion ist eben der Kern des Ganzen: sie schaut, ob es bereits eine Instanz gibt, und wenn nicht, erzeugt sie eine. Das verhindert, dass mehrere Instanzen erstellt werden.

Die Sache mit der Vererbung wird einfach gemacht, weil es immer der gleiche Aufbau ist, mit dem man eine Klasse zum Singleton macht. Warum also jedes mal wieder in die Klasse schreiben statt einfach einmal zu schreiben und dann einfach nur zu vererben?

Letztendlich ist aber ein Singleton eben auch nur wieder eine globale Variable und generell raten alle Programmierer mit etwas Erfahrung davon ab. Es kann zu diversen Problemen kommen, insbesondere wenn die Instanz des Singletons bereits zerstört war, und dann nochmal zugegriffen wird. Das führt dann dazu, dass eine neue Instanz erstellt wird. Das kann einerseits unerwartete Folgen z.B. im Logfile haben und andererseits kann es gut sein, dass man danach den delete vergisst und dann wieder ein Memoryleck produziert hat.

Nachtrag: Im Übrigen würde man sagen, die Logfile-Klasse ist das Singleton. Die Template-Klasse "Singleton" ist gewissermaßen eine Pseudo-Klasse, die eine andere Klasse zum Singleton macht, wenn man sie davon erben lässt. Das Einzige, was man davon später sieht, ist Get() und Del().

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »ridens« (04.09.2011, 12:01)


buggypixels

Treue Seele

Beiträge: 125

Wohnort: Meerbusch

Beruf: Programmierer

  • Private Nachricht senden

3

04.09.2011, 19:46

Das interessante an diesem Thema ist, dass immer wieder das Beispiel mit dem Logfile angeführt wird. Der Grund ist, dass es eines der ganz weniges überhaupt (einigermaßen) sinnvollen Beispielen
für den Einsatz eines Singleton ist. Aber selbst hier gibt es wesentlich bessere Implementierungen, die keinen Singleton verwenden.
Meiner Meinung nach erkennt man den schlechte Entwickler immer gerade an solchen Sachen. Wenn ich Singletons in einem Projekt sehe, dann weiß ich immer direkt recht gut bescheid.
Das geht dann in fast allen Fällen noch mit vielen anderen Programmiersünden einher. Jedenfalls kann man direkt gewarnt sein, dass hier ein Murkser vor dem Herrn zugange war.
Aber warum?
Wie bereits beschrieben sind Singleton nicht weiter als eine globale Variable. Warum man diese nicht einsetzen sollte, dürfte eigentlich klar sein. Wenn man schon Singletons verwendet, warum dann
nicht auch global direkt mal "int i, j, x, y, z" definieren? Die Variablen braucht man doch ständig in Schleifen usw.. Wäre doch praktisch. Seltsamerweise sträuben sich hier direkt allen die Haare.
Aber bei einem Singleton nicht. Das verstehe ich nicht.
Falls jemand Singletons verwendet, dann heißt das für mich immer:
a) er hat keine Lust sich Gedanken zu machen, wie und wo Instanzen einer solchen Klassen verwendet werden sollen und dürfen
b) er keinen Plan hat, wie man eine vernünftige Architektur definiert und somit auch die möglichen Zugriffe auf irgendwelche Instanzen.

Das lernt man im Laufe der Jahre. Als ich vor vielen, vielen Jahren anfing, da hab ich die Dinger auch verwendet. Aber man wird weiser im Alter.

ridens

Frischling

Beiträge: 47

Beruf: Freiberuflicher Entwickler

  • Private Nachricht senden

4

04.09.2011, 20:41

Joa und man darf ja als Anfänger auch noch auf ein paar vereinfachende Sünden zurückgreifen. Das erhält die Motivation besser, weil man sich weniger um komplizierte Mechanismen kümmern muss, und gleichzeitig sind Anfängerprojekte in der Regel klein genug, dass man den Überblick über sowas nicht verliert :)

Fred

Supermoderator

Beiträge: 2 121

Beruf: Softwareentwickler

  • Private Nachricht senden

5

04.09.2011, 20:44

Das Problem ist auch, dass viele einfach einen falschen Sinn in Singletons sehen. Singletons sollten nicht dafür verwendet werden von jeder Position Zugriff auf eine Klasse zu haben, denn dann ist das Singleton wirklich nur eine globale Variable. Dafür brauche ich dann nicht einmal eine Singleton-Klasse, sondern erstelle einfach eine globale Variable und kann diese nach Belieben verwenden. Da das aber ja ganz offensichtlich böse ist, muss man Singletons verwenden. Denn da ist die globale Variable noch ein bisschen versteckter und der Design-Schnitzer nicht ganz so offensichtlich

Oftmals ist es dann auch so, dass lange nicht jede Klasse auf das Singleton zugreifen müsste, sondern nur ein paar vereinzelte, denen dann aber relativ aufwändig eine Referenz mitgeliefert werden müsste. Das umgeht man einfach, indem man Singletons verwendet, was schlichtweg der falsche Ansatz ist.

Der Name "Singleton"(Einling) beschreibt es ja eigentlich schon. Singletons kann man dann verwenden, wenn man verhindern muss, dass aus irgendwelchen Gründen zwei Instanzen einer Klasse existieren.
Wer sich nun die Frage stellt, ob das nicht unglaublich selten ist, hat es erkannt ;). Es ist nur sehr selten der Fall, dass man wirklich nur eine einzige Klasseninstanz zulassen kann und somit ist die Verwendung von Singletons eben quasi nie sinnvoll.
Allerdings bin ich kein Freund von der Aussage "Singletons are evil". Ich behaupte, dass es sicher eine sinnvolle Anwendung von Singletons gibt(auch wenn ich sie bisher noch nicht gebraucht habe(aber wohl schon verwendet ;))). Nur kann man sich ziemlich sicher sein, wenn einem die Idee kommt, man könnte für ein bestimmtes Problem ein Singleton verwenden, dass es entweder ohne Singletons auch funktionieren würde oder das Design einen Fehler hat. Wenn man sich also nicht genaustens Überlegt hat, ob der Einsatz von Singletons in einem speziellem Fall unbedingt notwendig ist und sich nicht sicher ist, dass es wirklich keine andere Möglichkeit gibt, dann verwendet man Singletons falsch ;).

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

04.09.2011, 21:05

"Einling"? Spannendes Wort. Bisher kannte ich nur "Einzelstück". Mehr zum Thema gibt es aber wohl nicht sagen.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

7

04.09.2011, 22:29

Also statt einer globalen Variablen mach ich hier einfach eine Singleton-Klasse mit dieser Variablen und pack noch Funktionen mit rein. Theoretisch bräuchte ich die auch gar nicht sondern könnte das Zeug auch gleich in die Logfile-Klasse schreiben?
„lean over the bowl and then take a dive all of you are dead. i am alive“

ridens

Frischling

Beiträge: 47

Beruf: Freiberuflicher Entwickler

  • Private Nachricht senden

8

05.09.2011, 00:48

Der ursprüngliche Sinn ist nicht, eine globale Variable zu haben. Durch die Implementierung der Instanz als statische Variable gehts aber nicht anders. Es haben sich schon viele daran gemacht, die Probleme vom Singleton aufzuräumen, und trotzdem irgendwie zu verhindern, dass eine Klasse eine zweite Instanz bekommt. Dabei sind dann so Dinge wie das Phoenix-Singleton oder Monoid-Strukturen entstanden. Aber hier hat Fred schon recht: Es wird eigentlich nie wirklich notwendig sein, eine Klasse auf eine Instanz einzuschränken, wenn ansonsten keine Denkfehler im Konzept sind. Daher ist der ganze Gedanke um Singletons eigentlich unnötig.

Was das Buch angeht, als ich es zum ersten Mal durcharbeiten wollte, hat die Sache mit den Singletons und dem Logfile mich auch extrem verwirrt und mir die Motivation genommen. Im Buch wird allerdings am Ende, bei dem Beispiel mit der SDL das Singleton nochmal angewendet. Von daher würde ich mir keine Sorgen machen und die Kapitel um Singleton und Logfile überlesen/überspringen, und dann entweder
- im Beispiel am Ende statt Singletons einfach eine Instanz der Klasse global erstellen (wahlweise das Ding sauber programmieren und die Instanz eben nicht global machen), oder
- den Singleton-Code kopieren und anwenden, aber sich keine Gedanken drum machen, was das soll. Denn um das Beispiel komplett zu verstehen, ist es tatsächlich vollständig egal, was das Singleton da macht.

9

05.09.2011, 18:18

Man denkt manchmal, dass man es nun verstanden hat aber dann ist es doch noch etwas verwirrend.
Dazu kommt, dass es ausserdem ein Template ist und wir beim vererben als Typ die Logfile angeben ?!
„lean over the bowl and then take a dive all of you are dead. i am alive“

ridens

Frischling

Beiträge: 47

Beruf: Freiberuflicher Entwickler

  • Private Nachricht senden

10

05.09.2011, 20:12

Ich glaube was zunächst eben verwirrend sein kann vor allem, ist dass die Klasse als Membervariable eine Instanz von sich selbst hat. Versuch mal einfach, die Funktionen und Variablen einfach direkt in die Logfile-Klasse zu übernehmen (wobei du eben das T überall durch CLogfile ersetzt), dann halt ohne Vererbung... vielleicht wirds dann ja etwas weniger verwirrend weil Vererbung und Template wegfallen.

Werbeanzeige