Denkfehler Singleton

Status
Nicht offen für weitere Antworten.

dable

Mitglied
Ich hab hier das Grundgerüst eines einfachen Singletons.

Code:
public class Singleton
{ 
  private static Singleton instance = new Singleton(); 
 
  private Singleton() 
  { 
  } 
 
  public static Singleton getInstance() 
  { 
    return instance; 
  } 
 
}

Meine Frage dazu ist:
Die Eigenschaft instance ist ja ein Objekt der Klasse Singleton. Imho müsste dieses Objekt wieder eine Eigenschaft instance besitzen usw. Offensichtlich ist das nicht der Fall, sonst hätte man ja eine Endlosschleife. Wie kann das sein?
 
Weil Sie dank static einmal in der Klasse existiert nicht in der Instanz die du erstellst

instance.getClass() hätte wieder die Instanz
 
>> Denkfehler Singleton

Sehr wahr, Singleton ist ein Anti-Pattern.

>> Imho müsste dieses Objekt wieder eine Eigenschaft instance besitzen usw. Offensichtlich ist das nicht der Fall,

Nicht das Objekt, sondern die Klasse, weil instance static ist.
 
kurze zwischenfrage... wenn singleton so "böse" sind, warum sind dann standardmäßig alle "hippen" spring beans singletons..... ?
 
Alle die nicht anders deklariert sind, werden automatisch als Singleton gehandhabt

scope="prototype" 😉
 
Naja der Effekt ist ansich der Selbe. Es wird genau eine Instanz erstellt. Nur die Art und Weise wie diese Erstellung statt findet ist anders.
 
kurze zwischenfrage... wenn singleton so "böse" sind, warum sind dann standardmäßig alle "hippen" spring beans singletons..... ?
Gute Frage 🙂

Es git einen Unterschied zwischen einem "semantischem" Singleton (liefert immer dieselbe Instanz) wie Standard Spring Beans und einem syntaktischen Singleton (angeblich nur eine Instanz möglich, kein Interface möglich da statische Methoden, dadurch nicht austauschbar in tests), eben dem klassischen Singleton Krampf -> hardcodierte globale Variable .

Die statische Schnittstelle der syntaktischen Singletons sind das eigentliche Problem, dieses haben die semantischen Singletons eben nicht 😉

Juchu! Ein Singleton-Thread!:toll:
LMFAO
 
Zuletzt bearbeitet von einem Moderator:
Das "böse" an Singletons ist ja nicht die Tatsache, dass die Objekte nur einmal existieren dürfen, sondern der statische Zugriff auf die eine Instanz.
Spring Beans existieren per Default nur einmal, aber der statische Zugriff existiert ja nicht.
 
Naja der Effekt ist ansich der Selbe. Es wird genau eine Instanz erstellt. Nur die Art und Weise wie diese Erstellung statt findet ist anders.
Nein. Muster "Singleton" bedeutet: es ist garantiert, dass es nur ein Objekt des Typs gibt. Bei scope="singleton" ist das eben nicht der Fall. Du kannst 100 Beans definieren, alle vom selben Typ und alle mit Singleton-Scope.
 
Ok mit verschiedenen Ids 😉

Das könnte jetzt genauso eine Grundsatzdiskussion sein, wie ob ein static constructor einmal oder einmal pro classloader ausgeführt wird 😉
 
Wenn du nicht 2 verschiedene Beans mit 2 Qualifiern machst wird IMMER das eine Bean zurückgegeben, was genau dem Effekt des Singleton entspricht.

Gestern hatten wir die Diskussion ob ein "static constructor" nur einmal pro Programm ausgeführt wird. Für Anfänger ja. Für Fortgeschrittene nein, weil einmal pro Classloader.

Wenn du also Spring benutzt und jedes Interface nur einmal an ein Bean bindest bleibt der Effekt Singleton-Pattern.
 
Nein hast du nicht, weil diese Instanz nicht global erreichbar ist ^^

Das ist auch nicht Sinn eines Singletons, sondern nur ein Nebeneffekt bei der durch die GOF vorgeschlagenen Implementierung des Patterns.

Dein Beispiel mit den Spring Beans ist halt nicht vergleichbar. Denn der "Singleton-Effekt" bezieht sich in Spring nicht auf den Typ (also die Klasse), sondern auf die Bean-Definition.

Man kann durchaus mehrere Spring Beans des selben Typs mit scope singleton definieren. Und das sind dann zur Laufzeit auch unterschiedliche Objekte des selben Typs. Aber es sind halt auch unterschiedliche Beans.
 
[Haarspalterei]Darüber hinaus ist es ja nicht verboten, ein GOF-Singleton "package-protected" also nicht public zu definieren. Das wäre dann auch nicht global erreichbar, trotzdem ein Singleton.[/Haarspalterei]
 
Man kann durchaus mehrere Spring Beans des selben Typs mit scope singleton definieren. Und das sind dann zur Laufzeit auch unterschiedliche Objekte des selben Typs. Aber es sind halt auch unterschiedliche Beans.

Ja klar, aber eben unter der Voraussetzung, dass sie verschiedene Qualifier besitzen 😉

Egal, genau Haarspalterei ^^
 
Falsch. Der Qualifier hat damit gar nichts zu tun.
Du kannst zwei Beans desselben Typs ohne Qualifier deklarieren. Spring erzeugt dann zwei Objekte dieses Typs und nicht eins.

Als anonymes Bean 🙂

Aber zweimal das selbe Interface ohne Qualifier und als nicht anonymes Bean geht nicht. Wäre schon allein technisch nicht umsetzbar mit dem @Autowired Annotation, weil es die 2 Beans nicht auseinander halten könnte
 
Aber zweimal das selbe Interface ohne Qualifier und als nicht anonymes Bean geht nicht. Wäre schon allein technisch nicht umsetzbar mit dem @Autowired Annotation, weil es die 2 Beans nicht auseinander halten könnte

Der Qualifier (ID) muss per Definition eindeutig sein, richtig. Das hat aber nix mit dem Scope zu tun und noch weniger mit Singletons. 😉 Das funktioniert genauso wenig mit scope="prototype"...
 
>> Denkfehler Singleton

Sehr wahr, Singleton ist ein Anti-Pattern.
Nein. Singleton ist ein Muster und damit dem allgemeinen Problem unterworfen, dass man es nur dort einsetzen darf wo es tatsächlich Sinn ergibt. Das Hauptproblem an Mustern im allgemeinen ist, dass sie, aufgrund der Tatsache dass sie vorgefertigt existieren, schnell den Anschein erwecken, man könne sie eben mal anwenden ohne genauer darüber nachzudenken. Dann trifft man eben Entscheidungen die einer genaueren Prüfung nicht standgehalten hätten. Das passiert bei Singleton leider überdurchschnittlich oft.

Wenn die Realität des Problembereichs jedoch festlegt, dass es nur eine Instanz einer Art geben kann, dann ist das Singleton-Muster genau das richtige. Beispielsweise würde ich ohne zögern für ein Gebetsprogramm der katholischen Kirche die God-Klasse als Singleton konzipieren. Wenn diese Designgrundlage nicht mehr stimmt, dann nutzt das Programm ohnehin nichts mehr. :lol:

Das könnte jetzt genauso eine Grundsatzdiskussion sein, wie ob ein static constructor einmal oder einmal pro classloader ausgeführt wird 😉
Das Ding heißt Initializer, nicht Constructor. Ein Constructor erzeugt eine Instanz einer Klasse.

Ebenius
 
Nein. Singleton ist ein Muster und damit dem allgemeinen Problem unterworfen, dass man es nur dort einsetzen darf wo es tatsächlich Sinn ergibt. Das Hauptproblem an Mustern im allgemeinen ist, dass sie, aufgrund der Tatsache dass sie vorgefertigt existieren, schnell den Anschein erwecken, man könne sie eben mal anwenden ohne genauer darüber nachzudenken. Dann trifft man eben Entscheidungen die einer genaueren Prüfung nicht standgehalten hätten. Das passiert bei Singleton leider überdurchschnittlich oft.
Sehe ich anders.
Singleton ist nicht nur ein Anti-Pattern weil es falsch eingesetzt wird (globale Variable), sondern weil es in der vorgeschlagenen Form (static getInstance und interne Abhängigkeit zu instance) auch nicht testbar ist bzw. auch Tests von davon abhängigen Klassen sehr schwierig macht (schlecht testbares Design ist kein gutes Design).
Man erinnere sich nur an das von Sun vorgschlagene DAO Pattern inkl. abstrakter und konkreter DaoFactory.

Klar kann man Singleton auch vernünftig einsetzen, zB. wenn es nur intern in einer Klasse verwendet wird und von niemandem ausserhalb, aber dann kann man auch ohne Singleton gewährleisten das nur eine Instanz erzeugt wird.
 
Ich persönlich bin vorsichtig, wenn es darum geht, Muster die von Entitäten wie der Gang of Four publiziert wurden zum Anti-Pattern zu erklären. 🙂

PS: Ich bleibe bei meinem Gott-Beispiel oben. Es wäre extrem widersinnig, einen Gott mit Einzigartigkeitsanspruch in einer Fabrik zu fertigen und noch bekloppter, diese omnipräsente Entität als Argument für das Ziel des Gebetes zu übergeben. 🙂

Ebenius
 
Zuletzt bearbeitet:
Ich persönlich bin vorsichtig, wenn es darum geht, Muster die von Entitäten wie der Gang of Four publiziert wurden zum Anti-Pattern zu erklären. 🙂

Ebenius
Naja, zum Glück ist das ja nicht auf meinem Mist gewachsen 😉

Jedenfalls muss man einsehen dass dieses Buch aus einer Zeit stammt, in der OO zwar Hip aber noch nicht ganz verstanden war und Dinge wie "Dependency Injection" und Unittesting nicht weit verbreitet waren.
Das Original verwendet nicht die UML Notation (gab es damals noch nicht) und Beispiele wurden in C++ (würg) beschrieben.
Die anderen beschriebenen Muster sind immer noch oft verwendet und bei weitem nicht so umstritten.

Wobei es heute natürlich eine Flut von "Patterns" gibt die sich damals wohl niemand hätte träumen können...

PS: Ich bleibe bei meinem Gott-Beispiel oben. Es wäre extrem widersinnig, einen Gott mit Einzigartigkeitsanspruch in einer Fabrik zu fertigen und noch bekloppter, diese omnipräsente Entität als Argument für das Ziel des Gebetes zu übergeben.
Naja, glaube nicht das wir beide so gläubig sind dass wir wirklich davon ausgehen können jederzeit mit der Gott Instanz in kontakt treten zu können wenn wir wollten 😉
Abgesehen davon ist das "God Object" ein echtes Anti-Pattern (SCNR).
 
Zuletzt bearbeitet von einem Moderator:
Kann mich maki nur anschließen.

In meinen Augen sind Singletons mehr als unnötig und verleiten bloß dazu, statische Zugriffe quer über der gesamten Anwendung zu verteilen, was im schlimmsten Fall zu zyklischen Abhängigkeiten und Deadlocks führt.

Warum zum Geier muss eine Klasse zum Singleton werden, nur weil zur Laufzeit bloß eine Instanz der Klasse existiert? Reicht es nicht einfach, nur einmal den new Operator zu benutzen?

Das Spring Framework ist ein gutes Beispiel. Da gibts viele Klassen, von denen zur Laufzeit nur eine Instanz existiert (siehe z.B. AccessDecisionManager im Spring Security Modul). Trotzdem existieren immer öffentliche Konstruktoren.
 
Klar aber dann musst du irgendwo diese eine Instanz zugänglich machen, z.B. über eine rein statische Accessorklasse ApplicationContext oder wie auch immer du diese nennen willst 😉
 
Klar aber dann musst du irgendwo diese eine Instanz zugänglich machen, z.B. über eine rein statische Accessorklasse ApplicationContext oder wie auch immer du diese nennen willst 😉

Kommt drauf an, an wievielen Stellen diese Instanz gebraucht wird. Zunächst mal gibts ja die rein objektorientierte Lösung, Objektreferenzen beim Initialisieren zu übergeben. Nichts anderes machen DI Container wie Spring.

Händisch (also ohne DI Container) ist das natürlich etwas nervig, wenn gewissen Objekte an sehr vielen Stellen im Code gebraucht werden. In diesem Fall schreibe ich mir genau ein GOF Singleton mit statischem Zugriff und hänge alle global benötigten Objekte an dieses Singleton.
 
maki, ich würde jederzeit unterschreiben, dass das Singleton-Muster [HIGHLIGHT]umstritten[/HIGHLIGHT] ist. Ganz sicher auch, dass man es [HIGHLIGHT]mit Vorsicht[/HIGHLIGHT] einsetzen sollte. Auch, dass es [HIGHLIGHT]in der Regel[/HIGHLIGHT] die falsche Wahl ist. Und dass es um Längen [HIGHLIGHT]zu häufig benutzt[/HIGHLIGHT] wird. Als Anti-Pattern ist es trotzdem nicht anerkannt.

Ebenius
 
PS: Ich bleibe bei meinem Gott-Beispiel oben. Es wäre extrem widersinnig, einen Gott mit Einzigartigkeitsanspruch in einer Fabrik zu fertigen und noch bekloppter, diese omnipräsente Entität als Argument für das Ziel des Gebetes zu übergeben. 🙂
Wenn der katholische Gott so omnipotent ist, wie behauptet, kann er/sie auch mehrfach existieren wenn er/sie das möchte und auch austauschbar sein und von einer Fabrik erzeugt werden (wenn eine Instanz von er/sie die Fabrik dafür erzeugt) :bae:
 
Einverstanden Ebenius, bevorzuge aber aus rein polarisierenden Gründen den Begriff "Anti-Pattern" 😀

Mann muss imho auch unterscheiden zwischen dem GOF Singleton und Klassen von denen eben nur eine Instanz zur Laufzeit existiert (syntaktisch vs. semantisch).
Letzteres ist häufig der Fall, deswegen muss man aber nicht mehrere GoF Singletons haben.
DI Frameworks bieten Alternativen dafür und sogar für den "new" Operator an sich.

Klar habe ich das GoF Singleton auch mal benutzt und mittlerweile benutze ich manchmal immer noch als ein einzelnes in einer App(dann aber abgewandelt), was zwar gegen das sog. "Law of demeter" verstösst aber an machen Stellen durchaus vertretbar ist, so wie bei jeder Designentscheidung muss man halt immer abwägen.
 
maki, so werden wir uns tatsächlich einig. Unglaublich.

Nach dem Schuldbekenntnis kann ich jetzt also Deine Stimme in der Umfrage ändern, oder? 😉

Wildcard, ich glaube Gott spricht in der Deutschen Bibel in der Einzahl von sich und hat damit seine Entscheidung getroffen. Und die Omnipräsenz verbietet, dass er erzeugt wird, weil er schon da ist. Aber die Wege des Designs sind ja ebenfalls unergründlich. Quatsch, hab gut gelacht über Deinen Beitrag.

Ebenius.getInstance()
 
Was geht denn hier ab? Ich schliesse mich mal diesem hier an:
Ich persönlich bin vorsichtig, wenn es darum geht, Muster die von Entitäten wie der Gang of Four publiziert wurden zum Anti-Pattern zu erklären.
Während Singleton hier und da einfach NOTWENDIG! (entwickelt mal einen Service ohne... viel Spass) ist, gibt es eine Unzahl an Designpatterns die wirklich überflüssig sind und teilweise möglicherweise nur deswegen existieren, weil jemand Singleton nicht verstanden hat. Obwohl... ein "God-Singleton" ist ein schlechtes Beispiel für OOP "CatholicGod" dagegen nicht.
Mit Singleton signalisieren API-Entwickler, das von einer Klasse anwendungsweit nur eine Instanz existiert.
Ich als Entwickler muss eine Klasse meiner APIs, von der anwendungsweit nur eine Instanz existieren darf, als Singleton entwickeln. Verlässt diese Klasse mein API dagegen nicht (weil z.B. packagescoped), kann ich mich dazu entschliessen diese, nicht als Singleton zu entwickeln, wenn ich nur eine davon brauche.
 
Obwohl... ein "God-Singleton" ist ein schlechtes Beispiel für OOP "CatholicGod" dagegen nicht.
Darüber hatte ich nachgedacht. Wenn Du allerdings meinen Beitrag genau liest und Dir dann vorstellst, in gesagter Auftragsentwicklung der katholischen Kirche (deswegen hatte ich diese gewählt) die Designentscheidung zu treffen, es gebe einen abstrakten Gott und dann einen konkreten katholischen; dann hätte ich Dich gern in den Projekt-Treffen mit dem Auftraggeber erlebt. :lol:

Ebenius
 
Während Singleton hier und da einfach NOTWENDIG! (entwickelt mal einen Service ohne... viel Spass)
Um einen OSGi Service zu erstellen/publizieren, brauche ich kein Singleton.
Ich als Entwickler muss eine Klasse meiner APIs, von der anwendungsweit nur eine Instanz existieren darf, als Singleton entwickeln. Verlässt diese Klasse mein API dagegen nicht (weil z.B. packagescoped), kann ich mich dazu entschliessen diese, nicht als Singleton zu entwickeln, wenn ich nur eine davon brauche.
Nö. Du kannst auch einfach den Konstruktor mit default Visibility ausstatten, dafür braucht es kein Singleton.
 
Als Alternative hätte ich den Highlander nehmen können. Aber so ist's lustiger. Fakt ist, das Singleton lässt sich anhand des Beispiels nicht so einfach wegdiskutieren. 🙂

Ebenius
 
Nein, keine getInstance. Wer sagt, das der Konsument einer API sich die Instanz direkt bei der Klasse abholen muss? Ob etwas real ein Singleton ist, oder nicht, sehe ich eher als Implementierungsdetails, warum muss ich diese Entscheidung in einer API nach aussen tragen?
APIs müssen kompatibel bleiben und daher muss man noch viel viel vorsichtiger mit Singletons sein, weil du diese statische Referenzierung für den Konsument später nicht mehr transparent ändern kannst. Wenn sich aufgrund unvorhergesehener Ereignisse herausstellt, das ein Singleton keine gute Idee war, kann man es nie wieder auf kompatible Weise geradebiegen.
 
APIs müssen kompatibel bleiben und daher muss man noch viel viel vorsichtiger mit Singletons sein, weil du diese statische Referenzierung für den Konsument später nicht mehr transparent ändern kannst. Wenn sich aufgrund unvorhergesehener Ereignisse herausstellt, das ein Singleton keine gute Idee war, kann man es nie wieder auf kompatible Weise geradebiegen.
Diesen Teil unterschreibe ich so auch. Das ändert nichts daran, dass es eben Fälle gibt, in denen alle Kriterien gegeben sind. Es hängt nunmal immer vom Problembereich ab. In einem Kontext kann "OperatingSystem.getInstance()" legitim sein, in einem anderen nicht. Die Entscheidung lässt sich pauschal nicht treffen, in einem konkreten Problembereich jedoch schon. Aus dem Grund kann man auch nicht vom Anti-Pattern sprechen, weil dazu notwendig sein würde, dass das Pattern grundsätzlich ungültig wäre.

Ebenius
 
Das ändert nichts daran, dass es eben Fälle gibt, in denen alle Kriterien gegeben sind. Es hängt nunmal immer vom Problembereich ab. In einem Kontext kann "OperatingSystem.getInstance()" legitim sein, in einem anderen nicht. Die Entscheidung lässt sich pauschal nicht treffen, in einem konkreten Problembereich jedoch schon. Aus dem Grund kann man auch nicht vom Anti-Pattern sprechen, weil dazu notwendig sein würde, dass das Pattern grundsätzlich ungültig wäre.
Sehe ich genauso. Benutze das Pattern trotzdem nicht, weil ein echtes Singleton in Java nicht möglich ist, dann kann man es sich auch sparen.
Das Pattern als solches ist ein echtes Pattern, kein Anti-Patter, wird allerdings ständig falsch verwendet, hat sehr wenige Use-Cases und macht in Java nicht wirklich Sinn.
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben