Warum Singletons?
-
Shade Of Mine schrieb:
Simon2 schrieb:
Ein static an sich ist leider nicht threadsafe (sagt Matthew Wilson in "Imperfect C++")
Ein Singleton ansich ist auch nicht Threadsafe...
Das wissen aber viele nicht.
Bei einem Singleton ist auch klar, dass man nur entsprechende Memberfunktionen zugreift und dabei eine gewisse Funktionalität bereitstellt (zu der auch Serialisierung gehören kann).
WENN außerdem später doch ein Multithreading unterstützt werden soll, muß man beim singleton nur die Zugriffsfunktionen anpassen, während man bei einem "einfachen static" jeden einzelnen Zugriff rauspulen muß ...Gruß,
Simon2.
-
wisser schrieb:
Das Singleton-Muster wird zu 95% falsch eingesetzt.
99% der Thesen Unregistrierter sind zu schwach begründet.
Gruß,
Simon2.
-
Najo da hat er aber schon recht.
Und wie gesagt ein Singleton ist von Haus aus auch nicht threadsafe...
-
nep schrieb:
Najo da hat er aber schon recht...
Ich aber auch ! :p
BTW: Hat hier eigentlich irgendjemand behauptet, singletons seien von sich aus threadsafe ?
Solange das nicht der Fall ist, kann man vielleicht seine Gebetsmühlen wieder einpacken und mit diskutieren anfangen (wer will).Gruß,
Simon2.
-
3Fragezeichen schrieb:
Damit ich das Singleton austauschen kann muss ich ja ein interface zurückgeben und irgendwie wird dann das Singleton immer mehr zur Factory
Ansatzweise richtig erkannt, aber es liegt vielmehr daran, dass man das Singleton bei einer Schnittstelle nicht mehr direkt verwendet, sondern sich beispielsweise als Parameter übergeben lässt, wodurch also auch keine Notwendigkeit für den globalen Zugriff gegeben ist. Ich selbst geh auch immer öfter in Richtung Factory, die ich wenn nötig einfach zusätzlich entsprechend dekoriere, so dass nur eine Instanz erstellt wird. Ansich ist diese Grundsatzfrage vergleich mit der Frage um die Abhängigkeitsauflösung (Inversion of Control oder Service Locator).
Das Problem beim Singleton ist ja wie bereits erwähnt einfach, dass es zu leichtfertig verwendet wird. Die Vernetzung einzelner Software-Komponenten gestaltet sich oft aufgrund falscher Design-Maßnahmen als schwierig. "Dank" dem globalen Zugriff eines Singletons kann man diesen falschen Design-Maßnahmen entgegenwirken, zahlt aber einen sehr teueren Preis - hohe Kopplung. Wenn man allerdings zu Beginn schon nicht das richtige Design gewählt hat, wird einem diese zusätzliche Kopplung aber auch egal sein.
-
Simon2 schrieb:
WENN außerdem später doch ein Multithreading unterstützt werden soll, muß man beim singleton nur die Zugriffsfunktionen anpassen, während man bei einem "einfachen static" jeden einzelnen Zugriff rauspulen muß ...
Ne.
Du musst jede Methode synchronisieren. Es mag einige tricks geben wie zB Adapter, die dir das bei einem Singleton erleichtern, aber du musst jede Methode abwaegen und synchronisieren. getInstance() zu synchronisieren reicht nicht aus.
@TheBigW:
doof nur dass du damit keine Objekte mehr rumreichen kannst.
-
Löscht ihr singletons wieder? Was bringt das eigentlich? Es bleibt ja bis zum Programmende immer das selbe und wird dann vomOS automatisch gelöscht.
-
Warum bleibt es bis Programmende das Selbe?
-
andere frage schrieb:
Löscht ihr singletons wieder? Was bringt das eigentlich? Es bleibt ja bis zum Programmende immer das selbe und wird dann vomOS automatisch gelöscht.
nö. ich lösche singletons nicht. globale statische variablen sind für mich auch eine sorte singletons.
bei korrekt implementioerten singletons löscht c++ die irgendwie automatisch. gelöscht müssen sie aber werden bevor das bs den speicher wegräumen darf. zu leicht baut man später ein, daß das gesiglete objekt am ende eine datei schließen muss oder dergleichen.
-
doof nur dass du damit keine Objekte mehr rumreichen kannst.
@Shade
Naja, kommt doch auf den Anwendungsfall an, oder? Wenn ich ein Singleton habe, was nur eine public Memberfunktion hat, dann nervt es sicher (aus Anwendersich) auf Dauer, wenn ich immer erst meine Instanz holen muß. Wer sagt, das ich es unbedingt als Objekt herumreichen will/muß?
Ansich zeigt diese Diskussion doch nur, dass es DAS Singleton so im Detail nicht giebt. Sei es das Thema initialisierung/deinitialisierung, Zugriff oder was auch immer. Singleton sagt eben nur etwas über die Instanziierbarkeit aus und läßt die anderen Details im Dunkeln.
-
DAS Singleton gibt es sehr wohl und ist in einschlägiger Literatur beschrieben. Es ist halt ein Muster aus der Objektorientierten Programmierung und wird daher auch als Objekt behandelt. Nur weil DU der Meinung bist, ein Singleton nicht als Objekt zu verwenden, heisst das noch lange nicht, dass ein Singleton mehrdeutig ist.

Es bringt halt Vorteile mit sich, dass ein Singleton als Objekt behandelt wird. Du kannst das Objekt im Nachhinein spezialisieren, indem Du davon ableitest. Du kannst bei Bedarf refactorn, falls Du doch mal mehrere Instanzen erlauben willst. usw...
Wenn Du die Funktionalität statisch bereit stellst, dann kannst Du sie nie im Nachhinein polymorph überschreiben. -> unflexibel
-
So war das gar nicht gemeint. Es ging mir eher darum, das bei Singleton nicht automatisch das immer gleiche Vorgehen gemeint ist: ein Meyers Singleton und ein Phoenix Singleton sind nunmal unterschiedlich und trotzdem beide Singletons.
Es geht mir auch nicht darum hier zu sagen, das immer alle member statisch sein sollen. Ich sage nur, das es Fälle giebt wo das durchaus Sinn machen kann. Es schließt ja nicht mal aus, das man die Instanz trotzdem durch die Gegend reicht.
-
Mathias schrieb:
Warum bleibt es bis Programmende das Selbe?
Weil das doch gerade der Sinn des Singleton ist.
-
Shade Of Mine schrieb:
...getInstance() zu synchronisieren reicht nicht aus.
Wer hat denn etwas Anderes behauptet ?

Nochmal meine Aussage zum Nachlesen
Shade Of Mine schrieb:
Simon2 schrieb:
WENN außerdem später doch ein Multithreading unterstützt werden soll, muß man beim singleton nur die Zugriffsfunktionen anpassen, während man bei einem "einfachen static" jeden einzelnen Zugriff rauspulen muß ...
...
Falls das nicht klar war:
Bei einem Singleton auf Kapselung zu verzichten (also den direktn Zugriff auf (Nichtfunktions-)Attribute zuzulassen), halte ich für absoluten Quatsch.Natürlich kann ich auch globale statische Objekte entsprechend kapseln, aber nach meiner Erfahrung sind es oft sehr viel eher "globale ints, chars und strings", die angelegt und von allen Nutzern direkt manipuliert werden, während man - wenn man überhaupt auf die Idee gekommen ist, sich über den Zugriff Gedanken zu machen (z.B. im Rahmen eines singleton) - dann eher automatisch stark kapselt.
Serialisierung ist aber auch nicht die einzige "multithreadingrelevante Technik"; ein singleton kann man auch leicht so implementieren, daß unterschiedliche Prozesse/Systeme/Anwendungen/Programmiersprachen/... auf dasselbe Objekt zugreifen (letztlich kann getInstance() seine Daten "überall her" holen), während man mit static da ziemlich tricksen muß.Gruß,
Simon2.
-
gfsdf schrieb:
Mathias schrieb:
Warum bleibt es bis Programmende das Selbe?
Weil das doch gerade der Sinn des Singleton ist.
Der Sinn des Singleton ist, daß es NUR EIN Objekt des Typs gibt. Ob das während der gesamten Laufzeit das selbe ist, sei mal dahingestellt.
(und das klassische Singleton-Muster kann man auch so erweitern, daß man nicht auf "genau ein Objekt" beschränkt ist, sondern z.B. "maximal n Instanzen" erzeugen kann)
-
Damit es nur eines gibt muss es aber das selbe sein. Wenn du irgendwo einmal mit getInstance dir diese holst (und merkst), muss es die selbe bleiben, weil du sonst dem anderen der getInstance aufruft ein zweites object geben würdest, wenn es nicht das gleiche wäre.