Warum Singletons?
-
Wieso macht man nicht einfach alle functionen static? Man spart sich auch noch den ganzen instance Kram und das löschen (in C++).
Gibts was, was ich übersehen hab?
-
Wie du Singletones realisierst ist doch egal - wenn du meinst alles Static und Konstruktur private dann ist das doch auch in Ordnung
-
weil du dann auch alle daten static machen muesstest, dabei ist dann die initialisierung erst ausgefuehrt wenn du diese daten zum ersten mal verwendest und bei singletons moechte man ja gerade, dass beim ersten zugriff alle daten/member initialisiert sind.
-
Beispielimplmentation:
class Singleton { public: static Singleton* exemplar(); protected: Singleton() {} private: static Singleton *instanz; }; Singleton* Singleton::instanz = 0; Singleton* Singleton::exemplar() { if( instanz == 0 ) instanz = new Singleton(); return instanz; }Quelle: http://www.oop-trainer.de/Themen/Singleton.html
Ich weiss nicht, ist doch static

Singleton erlaubt nur das einmalige Erstellen eines Objektes.
-
@zeus: Ich glaube, der OP meinte, daß man eigentlich gar keine Instanz anlegen bräuchte und stattdessen über statische Memberfunktionen und Elemente arbeitet

@???: Der Vorteil davon ist, daß der Singleton erst angelegt wird, wenn er wirklich gebraucht wird - und das kann unter Umständen "nie" sein. Außerdem ist das System erweiterbar (du könntest z.B. auch mehrere Objekte der Klasse anlegen und verwalten).
-
Hi,
man sollte auch nicht vergessen, daß man über ein singleton ein Programm auch threadsafe machen kann, wenn mehrere Threads auf dieselben Daten (schreibend) zugreifen müssen (in "unserem" Server brauchen wir z.B. einen zentralen Zähler, von dem sich jeder Thread eine eindeutige Nummer abholen muß).. Ein static an sich ist leider nicht threadsafe (sagt Matthew Wilson in "Imperfect C++") ...
Gruß,
Simon2.
-
Simon2 schrieb:
Ein static an sich ist leider nicht threadsafe (sagt Matthew Wilson in "Imperfect C++")
Ein Singleton ansich ist auch nicht Threadsafe...
-
Hallo,
ganz einfach weil du bei lauter statischen Methoden eine noch viel höhere Kopplung erzielst, als es das Singleton ohnehin schon hat. Beim Singleton bestehen aber noch Möglichkeiten, wie das Implementieren einer Schnittstelle, zur Auflösung dieser Kopplung.
class Printer { public: virtual void printDocument(Document document) = 0; }; class LocalPrinter : Printer { private: LocalPrinter() { } public: virtual void printDocument(Document document) { // ... } static LocalPrinter& getInstance() { static LocalPrinter printer; return printer; } }; void printReports(Printer printer) { // ... } // anschließend der Aufruf: printReports(LocalPrinter::getInstance());
-
Das mit dem Initialisieren ist schonmal ne interessante Sache...
Bei einem Singelton werden alle Membervariablen zum gleichen Zeitpunkt initialisiert, ohne dass ich mir darüber Gedanken machen muß. Verwende ich n statische Variablen ist nicht definiert in welcher Reihenfolge diese initialisiert werden. Darum muß ich mich kümmern.
Singeltons müssen außerdem nicht zwingend beim Programmstart erzeugt und erst beim Programmende gelöscht werden. Wenn ich solche Objekte gerade nicht benötige kann ich sie löschen und bei Bedarf wieder erzeugen. Ich kann das Objekt auch als ganzes verwerfen und mir ein vollkommen anderes erzeugen.

-
Ich persönlich spar mir auch gerne das getInstance:
weil du dann auch alle daten static machen muesstest, dabei ist dann die initialisierung erst ausgefuehrt wenn du diese daten zum ersten mal verwendest und bei singletons moechte man ja gerade, dass beim ersten zugriff alle daten/member initialisiert sind.
nicht Zwangsläufig:
class MySingleton { public static PrintSingletonData(void) { cout << "My Singeltons data : " << m_Singelton.m_iSomeSingletonData << endl; } private: MySingleton() : m_iSomeSingletonData(0){} MySingleton m_Singelton; int m_iSomeSingletonData; }; MySingleton MySingleton::m_Singelton;Ich denke auch, das denjenigen, der das Singleton benutzt eigentlich die Instanz nicht interessieren sollte, sonder eher, was es tut.
@unkreativ003
Bei Deinem Beispiel fehlt die Implementierung von printReports und dort hast du dann eine Kopplung an Printer - gut: zugegeben, an einer Stelle zentral gekapselt.
-
TheBigW@Work schrieb:
@unkreativ003
Bei Deinem Beispiel fehlt die Implementierung von printReports und dort hast du dann eine Kopplung an Printer - gut: zugegeben, an einer Stelle zentral gekapselt.Die Kopplung zur "Schnittstelle" Printer ist ja auch egal, schon alleine weil eine Abhängigkeit zu einer Schnittstelle nicht zusätzlich auch noch transitive Abhängigkeiten mit sich bringt. Das Angenehme an dieser Vorgehensweise ist ja, dass das Singleton ersetzt werden kann, beispielsweise beim Testen. Gerade in Komponententests sind Singletons, bzw. singleton-ähnliche Konstruktre pures Gift, da man sie nicht durch Mock-Objekte oder ähnliches ersetzen kann.
-
Damit ich das Singleton austauschen kann muss ich ja ein interface zurückgeben und irgendwie wird dann das Singleton immer mehr zur Factory
-
Das Singleton-Muster wird zu 95% falsch eingesetzt.
-
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.