# Singleton und Vererbung?



## mad-din (12. Jun 2008)

Hi Leute!

Ich steh hier von einem kleinen großen Problem: ich hab für eine Anwendung von mir eine Singleton-Klasse geschrieben, die Daten aus einer Datenbank in eine HashMap lädt und die Methode getValue(keyname) kann man dann einen Wert aus der HashMap holen. Die Klasse ist deswegen ein Singleton, weil sie von vielen anderen Klassen gebraucht wird, aber eben nur einmal bestehen sollte, es wäre Schwachsinn, wenn jede Klasse die auf diese Daten zugreifen muss, jedesmal eine neue Instanz erzeugt. Soweit ja alles kein Problem. Die Klasse hat jetzt also eine HashMap und eine Methode getValue().
Jetzt ist aber die Anwendung gewachsen und ich brauch diese Klasse drei mal bzw. es müssen in dieser Anwendung drei dieser Instanzen vorhanden sein, aber jeweils mit unterschiedlichen Daten. Das einfachste wäre natürlich die Klasse zu kopieren, dann hätte ich Singleton1, Singleton2 und Singleton3 mit jeweils unterschiedlichen Daten. Aber das macht IMHO keinen Sinn und passt nicht wirklich in das Konzept von Objektorientierung. Also dachte ich mir ich mach eine Klasse Singleton, die als Basis die HashMap und die Methode hat. Zusätzlich hat diese eine Methode loadHashMap(), die die Daten lädt. Dann baue ich für jede weitere "Instanz" eine Klasse, die von Singleton erbt und nur die Methode loadHashMap() überschreibt. Aber das klappt nicht so ganz, da die HashMap im Singleton ja private ist und damit nicht überschrieben werden kann.

Weiß jemand Rat wie man so ein Problem am besten löst?

Danke & viele Grüße,
Martin


----------



## SlaterB (12. Jun 2008)

Vererbung und HashMap usw. klingt nach guten Ideen, aber die Singletons haben damit nix zu tun,
in jeder erbenden Klasse sollte der Singleton-Code a la

public static Klassenname singleton = new Klassenname();

einzeln für sich stehen, oder wie auch immer du das Singleton erzeugst, können ja nur paar Zeilen sein

-----------

alles weitere hat mit Singleton nichts mehr zu tun,
da der Begriff Singleton dein Posting (wie auch meine Antwort) dominiert, 
ist nicht so richtig klar, was ansonsten dein Problem bei der Vererbung ist,

die SubKlassen können natürlich nicht auf ein private Feld der OberKlasse zugreifen, 
aber gibt ja auch set-Operationen oder die OberKlasse könnte das selber speichern:

this.map = loadHashMap();


----------



## Wildcard (12. Jun 2008)

Singeltons benutzt man genau dann, wenn es von einer Klasse nur eine Instanz geben *darf*.
Da diese Bedingung bei dir wohl nicht zutrifft, ist ein Singelton der falsche Ansatz.


----------



## SlaterB (12. Jun 2008)

@Wildcard: wieso ist bei Singleton Vererbung verboten?
muss jedes Singleton hashCode() selber implementieren?


----------



## maki (12. Jun 2008)

static lässt sich nicht so einfach vererben


----------



## mad-din (12. Jun 2008)

Wildcard hat gesagt.:
			
		

> Singeltons benutzt man genau dann, wenn es von einer Klasse nur eine Instanz geben *darf*.
> Da diese Bedingung bei dir wohl nicht zutrifft, ist ein Singelton der falsche Ansatz.



Mag sein, dass Singleton vielleicht nicht der richtige Begriff dafür ist, aber wie sollte es sonst lauten: drei Klassen, die die gleiche Logik beinhalten, jedoch unterschiedliche Daten und von jeder dieser drei Klassen darf es nur eine Instanz geben? Im Grunde sind es drei ja drei Singletons, die nur eben das gleiche machen. Wie sollte man sowas realisieren, wenn nicht mit Singletons?



			
				SlaterB hat gesagt.:
			
		

> Vererbung und HashMap usw. klingt nach guten Ideen, aber die Singletons haben damit nix zu tun,
> in jeder erbenden Klasse sollte der Singleton-Code a la
> 
> public static Klassenname singleton = new Klassenname();
> ...



Genau das will ich aber vermeiden, weil dann kann ich die drei Klassen auch einzeln für sich schreiben bzw. eine schreiben und dann immer kopieren. 

So sieht im Grunde die Singleton-Klasse aus:


```
public class Singleton {

	private static Singleton instance;
	private HashMap<String, String> data;
	
	private Singleton() {
		this.loadData();
	}
	
	private void loadData() {
		this.data = new HashMap<String, String>();
		data.put("test", "wert");
	}
	
	public Singleton getInstance() {
		if (Singleton.instance == null) {
			Singleton.instance = new Singleton();
		}
		return Singleton.instance;
	}
	
	public String getValue(String key) {
		return this.data.get(key);
	}
	
}
```

Jetzt brauche ich noch eine Singleton2, die aber andere Daten in die HashMap lädt. Kann man das nicht mit Vererbung so hinbekommen, dass ich nur noch eine Klasse schreiben brauch, die im Grunde nur loadData() überschreibt?

Viele Grüße,
Martin


----------



## Illuvatar (12. Jun 2008)

SlaterB hat gesagt.:
			
		

> @Wildcard: wieso ist bei Singleton Vererbung verboten?



Naja, es macht imo zumindest nicht viel Sinn...
Wenn wir eine Singleton-Klasse "TollesSingleton" haben, definiert diese, dass es genau ein TollesSingleton gibt, und instanziert dieses auch gleich mit "new TollesSingleton()". Wenn wir jetzt davon Kindklassen haben, kann es davon logischerweise keine Instanzen geben, weil es ja schon ein TollesSingleton gibt...


----------



## SlaterB (12. Jun 2008)

@Illuvatar
nun, die Basisklasse ist ja auch nicht das Singleton,
sondern die erbenden Klassen, diese müssen final sein bzw. der private Konstuktor erledigt das ja,

aber dass drei unterschiedliche Singleton von einer Basisklasse wie ArrayList erben ist doch ok

--------

@mad-din
tja, ich kann da einfach nur mein Posting wiederholen


> Vererbung und HashMap usw. klingt nach guten Ideen, aber die Singletons haben damit nix zu tun,
> in jeder erbenden Klasse sollte der Singleton-Code a la
> 
> public static Klassenname singleton = new Klassenname();
> ...


ok, sollte klingt etwas schwach, es ist nunmal so: diese begrenzten 5 Zeilen der statischen Variable + Konstruktor-Aufruf kannst du dir nicht sparen, fertig!

sparen kannst du dir 10.000 Zeilen Code zum Laden/ Verarbeiten der Map oder ähnlichem, 
falls in allen Klassen gleich und überhaupt vorhanden


----------



## mad-din (12. Jun 2008)

SlaterB hat gesagt.:
			
		

> sparen kannst du dir 10.000 Zeilen Code zum Laden/ Verarbeiten der Map oder ähnlichem,
> falls in allen Klassen gleich und überhaupt vorhanden



Ok, dann kann ich mir quasi gar nix sparen  Weil im Grunde ist nur die Methode getValue() bei allen gleich, das Laden in den Klassen ist jeweils unterschiedlich. 
Bleibt mir also nichts anderes übrig, also die Klasse drei mal zu schreiben (wird nur später dann mühsam, weil da durchaus noch mehr hinzukommen können).

Danke & viele Grüße,
Martin


----------



## Wildcard (12. Jun 2008)

Ich kann mir nun wirklich nicht vorstellen das diese Anforderung irgendwas mit Singelton zu tun haben soll.
Schau dir vielleicht mal das Strategy Pattern o.ä. an, oder rück ein paar mehr INformationen raus.


----------



## mad-din (12. Jun 2008)

Hi!

Es geht um folgendes: eine Anwendung erzeugt täglich zwei Textdateien mit Aufträgen und Kunden eines OnlineShops. Da in diesen Textdateien neben den Kunden- und Auftragsdaten verschiedene Konfigurationsdaten enthalten sein müssen, gibt es eine Singleton-Klasse Configuration, die die Konfiguration des OnlineShops aus der Datenbank ausliest. Diese Schnittstelle wird nun auf mehrere OnlineShops (derzeit 3) erweitert, das heißt sie erzeugt nicht nur 2 Textdateien, sondern insgesamt sechs, zwei für jeden OnlineShop. Da aber die Konfiguration der OnlineShops unterschiedlich ist, muss auch in dem Programm für jeden Shop die Konfiguration geladen werden, die selbstverständlicherweise als Singleton in dem Programm auftritt.

Viele Grüße,
Martin


----------



## Saxony (12. Jun 2008)

mad-din hat gesagt.:
			
		

> So sieht im Grunde die Singleton-Klasse aus:
> 
> 
> ```
> ...



Mach dann aber bitte deine Singletons so, wie es schon SlaterB geschrieben hatte:


```
private static Singleton instance = new Singleton();
```

Also ohne if blafasel == null usw. erspart dir im weiteren Verlauf so manchen Ärger! 

Erklärung dazu!

bye Saxony


----------



## mad-din (12. Jun 2008)

Hi!

Ist vorgemerkt  Bei der jetzigen Anwendung ist es zwar egal, weil das eine Single-Thread Anwendung ist und das auch bleibt, aber für andere Anwendungen kann man das gut gebrauchen 

Danke & viele Grüße,
Martin


----------



## Guest (14. Jun 2008)

mad-din hat gesagt.:
			
		

> Die Klasse ist deswegen ein Singleton, weil sie von vielen anderen Klassen gebraucht wird, aber eben nur einmal bestehen sollte, es wäre Schwachsinn, wenn jede Klasse die auf diese Daten zugreifen muss, jedesmal eine neue Instanz erzeugt.


Wenn viele andere Klassen dasselbe Datenbankexemplar brauchen, dann sorge dafür, dass sie es irgendwie bekommen. Deswegen das Singletonpattern zu verwenden ist falsch, was Du ja eigentlich schon selbst gemerkt hast, da Du ja auf einmal doch mehrere Instanzen brauchst.

Das Singleton wird in 90% der Fälle aus purer Faulheit eingesetzt, damit man sich nicht um einen ordentlichen OO-Entwurf kümmern muss. Ein Singleton ist GLOBAL verfügbar und somit die schlechteste Form von Kopplung (nämlich maximal hoher).

Just say NO to singletons. They are evil.


----------



## Wildcard (14. Jun 2008)

Anonymous hat gesagt.:
			
		

> Just say NO to singletons. They are evil.


ACK. Hast du auch passende Anstecknadeln?


----------



## SlaterB (14. Jun 2008)

wer sowas sagt darf auch System.out nicht verwenden,

Say NO to System.out und allen statischen Operationen wie Math, Collections usw, verbietet das Schlüsselwort static
 :autsch: 


Leute, solche Anfängerfragen sind Anfängerprobleme, hier gehts nicht um 100 Klassen-Projekte wo eine fragile Ordnung aus den Fugen gerät, 
bei einfachen Programmen schadet statisch so gut wie nie.., es gibt nicht mal mehrere Threads und dahingehende Probleme


----------



## Wildcard (14. Jun 2008)

System.out ist statisch, kein Singelton.
An statisch ist auch nichts verkehrt, das hat seine Berechtigung, ebenso wie Singeltons (in ganz ganz speziellen Fällen).
Das Problem an Singelton ist:
Es wird ständig falsch angewendet. Wenn man die betreffenden Spezis dann darauf anspricht, ist es auf einmal kein schlechtes Softwaredesign mehr, denn sie haben ja ein _Design Pattern_ benutzt  :autsch:


----------



## SlaterB (14. Jun 2008)

System.out ist eine Ressource, ein Objekt welches die Ausgabe regelt,
niemand würde auf die Idee kommen, so ein Objekt per Parameter herumzureichen,

ich frage mich wieso das ständig bei allen anderen Arten von Objekten vorgeschlagen wird,
es gibt so viele einfache Programme, wo es einen GUI-Controller, eine DB-Verbindungsklasse, eine Datenmenge (oder drei unterischiedliche) gibt,
absolut nichts spricht dagegen, einen total einfachen statischen Zugriff zu bauen,
aber wann immer man daran denkt ein einzelnes Objekt statisch bekannt zumachen statt per zig Parameter herumzureichen gibts immer einen Nervenzusammenbruch,
oh Gott, auf englisch heißt das ja 'Singleton', das böse Anti-Pattern..

was kann bitte an System.out schiefgehen?, warum sollte man diesen Printstream an jede Operation im Programm per Parameter herumreichen?
so und wenn das geklärt ist: warum sollten für andere Objekte andere Regeln gelten?
klar, wenn mehrere Threads laufen, kann man so nicht arbeiten,
klar, wenn jeder JButton einer GUI einzeln statisch ist und von anderen Klassen angesprochen wird, geht jede Übersicht verloren,

aber wenn jemand etwas von sich aus Singleton nennt, dann ist das in den meisten Fällen, so wie hier, eine durchdachte Sache,
ein große Datenmenge die unter einen bestimmten Namen im Programm global bekannt ist statt mühsam überall mitgeschleppt zu werden,
ich kann mir nicht vorstellen dass dadurch irgendeine Übersichtlichkeit leidet,


----------



## Wildcard (14. Jun 2008)

System.out ist kein Singelton.
Statische Zugriffe sind wichtig. Alles was statisch sein kann, soll auch statisch sein.
Warum aber für jeden Mist dieses Pseudo-Objekt SIngelton an Stellen wo es laut Pattern Beschreibung überhaupt nichts zu suchen hat?
Am besten noch mit double checked locking um die Suppe komplett zu versalzen.
Warum kein einfaches, ehrliches static?


----------



## SlaterB (14. Jun 2008)

wenn du die statische Variable nicht schlimm findest, dann sind wir hier ja einer Meinung,
über das vermeintliche Lazy Loading durch getInstance() ohne Funktion kann man ja hinwegsehen,
das schnappt man so auf ohne drüber nachzudenken, stört ja nicht 

ich bezog mich auf den Vorschlag zur Parameterübergabe:


			
				Anonymous hat gesagt.:
			
		

> Wenn viele andere Klassen dasselbe Datenbankexemplar brauchen, dann sorge dafür, dass sie es irgendwie bekommen.



edit:
der Satz vom Anfang


			
				Wildcard hat gesagt.:
			
		

> Singeltons benutzt man genau dann, wenn es von einer Klasse nur eine Instanz geben *darf*.
> Da diese Bedingung bei dir wohl nicht zutrifft, ist ein Singelton der falsche Ansatz.


ist dann wohl auch nur Definitionsgepoche?
in Anfängerfragen ist doch fast immer mit Singleton einfach nur eine statische Variable gemeint..


----------



## Wildcard (14. Jun 2008)

> wenn du die statische Variable nicht schlimm findest, dann sind wir hier ja einer Meinung,
> über das vermeintliche Lazy Loading durch getInstance() ohne Funktion kann man ja hinwegsehen,
> das schnappt man so auf ohne drüber nachzudenken, stört ja nicht


Richtig, funktional stört es nicht (solange kein double checked locking vorkommt), ich bin es nur leid sowas dann immer wieder als _Pattern_ verkauft zu bekommen, das ist es nämlich definitiv nicht.

EDIT:



> der Satz vom Anfang
> 
> 
> 
> ...


Meinst du?  ???:L 
Für mich ist Singelton und statisch echt distinkt. Eine statische Zugriffsmethode ist ja eigentlich nur ein Implementierungsdetail der Singelton-Idee:
Verhindere das es mehr als eine Instanz einer Klasse geben kann, und mach sie überall verfügbar.


----------



## Guest (15. Jun 2008)

System.out ist eine ganz andere Schiene: eine statische Konstante in der Klasse System vom Typ PrintStream. Niemand hindert Dich daran, weitere PrintStream Objekte zu erstellen und anderweitig zu verwenden. Genau das tut aber das Singleton-Pattern. Es VERBIETET Dir, mehr als eine Instanz zu erzeugen. Und das ist in 90%, ach was sag ich, 99,9% der Fälle unangebracht.

Wenn der Fragesteller unbedingt drei global erreichbare Datenbankverbindungen oder was auch immer haben möchte, dann soll er sie doch einfach zur Verfügung stellen:


```
class X
{
    public static final X instanz1 = new X("foo");
    public static final X instanz2 = new X("bar");
    public static final X instanz3 = new X("baz");

// ...
}
```

Es gibt aber ABSOLUT keinen Grund, den Klienten weitere Instanziierungen dieser Klasse zu VERBIETEN und dafür auch noch (fehleranfälligen) Boiler-Code zu schreiben. Wenn er nicht mehr als drei Exemplare braucht, dann soll er sie einfach nicht erstellen. Dafür braucht man kein Singleton.

Ein Singleton würde hier sagen: die Welt gerät aus den Fugen, sobald jemand mehr als eine (oder auch drei) Datenbankverbindungen herstellt. Mehrere Datenbankverbindungen sind UNDENKBAR und müssen UNBEDINGT VERHINDERT werden. Will man das? Nein, die Anfänger wollen einfach nur ihren statischen, globalen Zugriff. Sollen sie haben, aber dafür braucht man kein Singleton.

Just say NO to singletons. They are evil.


----------



## Guest (15. Jun 2008)

mad-din hat gesagt.:
			
		

> Die Klasse ist deswegen ein Singleton, weil sie von vielen anderen Klassen gebraucht wird


Liste diese Klassen doch mal kurz auf. Sind es wirklich so viele?


----------



## SlaterB (15. Jun 2008)

Anonymous hat gesagt.:
			
		

> Just say NO to singletons. They are evil.


falls du der gast mit dem ersten derartigen Spruch bist,
dann hast du diesmal wenigstens nicht wiederholt, dass die statische Variable schlecht ist 
und dass selbst wichtige zentrale Objekte zwangsweise als Parameter rumgereicht werden müssen,
da bin ich schon mal froh,

------

so, bleibt noch das Verhindern von mehrereren Instanzen,
das Laden der Daten dauert x Sekunden (oder auch nur MilliSekunden) und belegt x MB des Speichers (oder auch nur KB),
es macht im Programm keinen Sinn die Daten doppelt vorzuhalten, daher wird durch einen private Konstruktor verhindert, dass dies versehentlich passiert,

kann mir bitte irgendjemand erklären, was an so einer simplen Sache verkehrt sein kann?
ich kann in die Köpfe solch sturer Menschen nicht reinblicken, was bewegt jemanden zu so einer Aussage? 

irgendwelche Erfahrungen aus Großprojeken nehme ich immer an, aber muss man die wirklich gleich an jeden Anfänger weiterreichen?



> Es VERBIETET Dir, mehr als eine Instanz zu erzeugen. Und das ist in 90%, ach was sag ich, 99,9% der Fälle unangebracht.





> Mehrere Datenbankverbindungen sind UNDENKBAR und müssen UNBEDINGT VERHINDERT werden. Will man das? Nein


doch will man, wo ist da ein Problem? 

im besten Fall sind mehrere gleiche Objekte noch nur unnötige Replikation,
wenn es aber um den Austausch von Informationen geht, dann wird das richtig böse


----------



## Wildcard (15. Jun 2008)

Ich kann mich Gast nur 100% anschließen.
Bei SIngelton geht es primär darum, eine zweite Instanzierung einer Klasse unbedingt zu verhindern.
Es geht nicht darum ob eine zweite Instanz unnütz, oder 'Speicherverschendung' ist, sondern darum, das es keine zweite Instanz geben *darf*.
Wenn man statische Methoden für XY braucht. Kein Problem 

```
static doFooWith(Object stuff)
{

}
```

Dafür gibt es static.
*Aber*: Kein Singelton, es sei denn es ist ein echtes Singelton (es *darf* keine zweite Instanz geben).
In diesem Fall wird aus dem aus Singeltons bekannten Code nämlich ein sinnfreies Gebilde das lediglich die wahre Natur des statischen Zugriffs verschleiert.
Ein wichtiger Aspekt der Design Patterns besteht im Wiedererkennungswert.
Entwickler die die gängen Patterns kennen, finden sich in fremdem, pattern-orientierten Code schnell zurecht. Pseudo SIngeltons und andere, missbrauchte Patters verwaschen diesen Wiedererkennungswert und verstoßen gegen den Grundsatz ehrlichen Code zu schreiben.


----------



## SlaterB (15. Jun 2008)

das ist nun wieder Definitionsreiterei,

mir begegnen tagtäglich Situationen im Code und Topics hier im Forum, 
wo es darum geht, dass man nur ein Objekt einer Klasse brauch

-> private Konstruktor und statisch eine Instanz,

eine Instanz der Klasse, das ist der Kern, 

und dass dafür der Name 'Singleton' verwendet wird, kann man niemanden ausreden 
auch wenn damit vielleicht in irgendwelchen wirren Büchern was anderes gemeint ist, 
das wäre eine zu große Aufgabe


----------



## Wildcard (15. Jun 2008)

SlaterB hat gesagt.:
			
		

> eine Instanz der Klasse, das ist der Kern


Ich zitiere kurz:
http://blogs.msdn.com/scottdensmore/archive/2004/05/25/140827.aspx


> *  Singletons allow you to limit creation of your objects.*
> This is true, but now you are mixing two different responsibilities into the same class, which is a violation of the Single Responsibility Principle. A class should not care whether or not it is a singleton. It should be concerned with its business responsibilities only. If you want to limit the ability to instantiate some class, create a factory or builder object that encapsulates creation, and in there, limit creation as you wish. Now the responsibilities of creation are partitioned away from the responsibilities of the business entity.



Mehr Quellen:
http://www.c2.com/cgi/wiki?SimpletonPattern
http://www.c2.com/cgi/wiki?SingletonsAreEvil


----------



## SlaterB (15. Jun 2008)

wenn du mir irgendwas damit sagen willst, dann ist es leider nicht zu mir durchgedrungen

ich lese daraus evtl. die Behauptung, dass man in Java-Programmen keine private Konstruktoren verwenden sollte, 
sondern den Overhead (in einfachen Fällen sinnloser) zusätzlicher Factories,
und dass dann immer noch jemand aus Versehen ein Objekt normal erstellen kann ist eben Pech,

aha..


----------



## Gast (15. Jun 2008)

für mich bedeutet "ehrlicher code" auch, dass ich meinen code so gestalte, dass völlig unmisverständlich klargestellt wird, wie er zu verwenden ist.

wenn ich eine klasse schreibe, die nur einen bestimmten, lokalen zweck erfüllt, dann bekommt sie package scope, evtl. sogar eine inner class.

wenn ich eine klasse schreibe, für die es keinen sinn macht, sie zu instantiieren, weil sie nur ein paar statische methoden anbietet oder konstanten vorhält, dann bekommt sie einen privaten konstruktor.

und wenn ich eine klasse schreibe, von der man niemals mehr als eine instanz braucht, dann sorge ich dafür, dass dies auch nicht möglich ist.

ich hab schon zuviel code gesehen, der innerhalb kürzester zeit unübersichtlich und schlecht wartbar wurde, einfach weil jede noch so komische klasse vollständig als public deklariert und nirgendwo sinnfreie instantiierung unterbunden wurde.
allein das "simple bean" verfahren, jeder klasse einen standard-konstruktor zu verpassen, anstatt lediglich konstruktoren anzubieten, die sinnvolle objekte erzeugen können, hat schon für viele schmerzen gesorgt.


----------



## Wildcard (15. Jun 2008)

> und wenn ich eine klasse schreibe, von der man niemals mehr als eine instanz braucht, dann sorge ich dafür, dass dies auch nicht möglich ist.


*Das* dürfte schwierig werden, aber den Rest würde ich unterschreiben


----------



## Gast (15. Jun 2008)

sollte es irgendwann in der zukunft doch noch nötig werden, dass man von einer klasse mehr als eine instanz benötigt wid, dann kann man ja durchaus vorsichtig refaktorieren.


----------



## Guest (15. Jun 2008)

Gast hat gesagt.:
			
		

> und wenn ich eine klasse schreibe, von der man niemals mehr als eine instanz braucht, dann sorge ich dafür, dass dies auch nicht möglich ist.


Das ist einfach falsch argumentiert. "Momentan nur eine Instanz brauchen" ist nicht dasselbe wie "Es ist grundsätzlich nur eine Instanz vorstellbar, mehrfache Instanziierung muss unter allen Umständen mit zusätzlichem Code verhindert werden". Letzteres macht das Singleton. Es VERBIETET mehrere Exemplare.

Nun schau Dir an, was der OP will: er möchte drei Exemplare der Klasse haben. Warum erstellt er diese drei Exemplare nicht einfach? Warum will er über Vererbung oder Copy&Paste neue Klassen erstellen, von denen dann jeweils wieder nur ein Exemplar existieren darf? Warum erstellt er nicht einfach genau die Exemplare, die er braucht?

Wenn ich mir ein System angucke und merke, dass ich von Klasse A nur n Exemplare erstelle, muss ich dann anschließend den Quellcode so abändern, dass ich auf keinen Fall mehr als n Exemplare erstellen kann? NEIN. Ich erstelle einfach nur genau die Exemplare, die ich brauche. Das ist OO. Alles andere ist Schwachsinn.

Warum benutzt man eine objektorientierte Programmiersprache wie Java und weigert sich, objektorientiert zu programmieren?
- Eine Klasse sollte gar nicht wissen, welche Klienten Exemplare von ihr benötigen.
- Eine Klasse sollte nicht verbieten, dass man Exemplare von ihr erstellt.
- Global verfügbare Objekte haben maximale Kopplung (JEDER kann darauf zugreifen) und sind daher sehr schlecht testbar. Ausnahme: unveränderliche Objekte sind weitestgehend unproblematisch.

Das Problem ist, dass viele Leute sich einreden, ihren Code mit dem Singleton-Pattern irgendwie "objektorientierter" zu machen. Genau das Gegenteil ist der Fall. NICHTS am Singleton-Pattern in objektorientiert, und es ist fast IMMER unangebracht, es zu verwenden. Meistens kennen solche Leute auch gar keinen anderen Patterns.

Die Module in einem objektorientierten System sollten lose gekoppelt sein. Es darf also gar nicht mehr als zwei oder drei Module geben, die überhaupt von der Existenz dieser Datenbankklasse wissen. Wenn jemand tatsächlich in seinem ganzen System Referenzen herumreichen muss, dann muss er zu einem besseren Klassenentwurf hin refactorn, NICHT zu einer globalen Variable oder (noch viel schlimmer) zu einem Singleton, was gar nicht das tut, was er möchte (es ist global UND es hat diese dämliche Beschränkung eines einzigen Exemplars).

Why are you infected with Singletonitis?

Just say NO to singletons. They are evil.


----------



## SlaterB (16. Jun 2008)

Anonymous hat gesagt.:
			
		

> Nun schau Dir an, was der OP will: er möchte drei Exemplare der Klasse haben. Warum erstellt er diese drei Exemplare nicht einfach? Warum will er über Vererbung oder Copy&Paste neue Klassen erstellen, von denen dann jeweils wieder nur ein Exemplar existieren darf? Warum erstellt er nicht einfach genau die Exemplare, die er braucht?


an dieser Stelle muss selbst ich als großer Kritiker zugeben, das hier gut möglich drei Objekte der gleichen Klasse benötigt werden 

um was genau es geht weiß man natürlich nicht




> Wenn ich mir ein System angucke und merke, dass ich von Klasse A nur n Exemplare erstelle, muss ich dann anschließend den Quellcode so abändern, dass ich auf keinen Fall mehr als n Exemplare erstellen kann? NEIN. Ich erstelle einfach nur genau die Exemplare, die ich brauche. Das ist OO. Alles andere ist Schwachsinn.


n != 1?
private Konstruktoren und bestimmte abstrakte Klassen in Java sind Schwachsinn? gut zu wissen



> - Eine Klasse sollte gar nicht wissen, welche Klienten Exemplare von ihr benötigen.


um es auch mal genau zu nehmen: implements TableModel? 
aber stimmt natürlich



> - Eine Klasse sollte nicht verbieten, dass man Exemplare von ihr erstellt.


ich wünschte es gäbe dafür auch mal eine Begründung,

wenn es der ausdrückliche Sinn in einem Programm ist, dass diese Erstellung kontrolliert wird, warum nicht?
aus reinen Spass, einen OO-Buch blind gefolgt zu sein, noch eine sinnlose Factory-Klasse daneben-betonieren?



> - Global verfügbare Objekte haben maximale Kopplung (JEDER kann darauf zugreifen) und sind daher sehr schlecht testbar. Ausnahme: unveränderliche Objekte sind weitestgehend unproblematisch.


das System.out-Argument



> Die Module in einem objektorientierten System sollten lose gekoppelt sein. [..]
> 
> Why are you infected with Singletonitis?


+ aus dem Link


> Proper refactorings can eliminate the majority of deep pointer passings that are required in order to get an object to where it needs to go. Furthermore it will properly centralize common code and allow the removal of a great deal of duplication.


wer in solchen Dimensionen programmiert muss darüber nicht diskutieren, in derartigen Systemen gibts über Singletons keine solchen Fragen,
aber nochmal: auf Anfänger-Spatzen mit solchen Kanonen zu schießen ist kontraproduktiv


----------



## Wildcard (16. Jun 2008)

Ich finde gerade Anfänger sollten über best-practices Informiert werden. Ausserdem sind wir gar nicht im Anfänger-, sondern im Allgemeinen Bereich. Und in weniger komplexen Systemen, stellt sich die Notwendigkeit eines global verfügbaren Objekts noch viel weniger, da man Referenzen auch bei schlechtem Design nicht durch 50 Ebenen schleifen muss.


----------



## SlaterB (16. Jun 2008)

das Niveau der Frage lässt nur eine Interpretation zu, mit Verlaub 

das andere ist gerne Ansichtssache, 
aus meiner Sicher stellt sich in weniger komplexen Systemen die Notwendigkeit nach einem das ganze erst kompliziert machenden Framework weniger als simple globale Referenzen,

ein guter Indikator dafür ist System.out vs irgendein Logging-Framework oder Einbau einer GUI-Ausgabe für interne Meldungen,
wenn ersteres durch letzteres ersetzt wird, dann kann man auch alle anderen statischen Variablen in Frage stellen


----------



## Saxony (16. Jun 2008)

Hiho,

ähm Wildcard - wieso sollte ich bei einem 3-5 Klassen Programm noch zusätzlich Factory bzw. Builder Klassen schreiben, nur weil ich mal eine meiner Klasse nur einmal erstellen will? Leuchtet mir gerade nicht so direkt ein! Weil wie SlaterB schon schreibt, ist bei MiniProgrammen und vor allem im Anfängerbereich sinnvoller den Leuten nicht gleich den Spass am proggn zu nehmen! Was du in deinen extrem mächtigen Mammutprojekten für Factorys einbaust, will ja kein Aas wissen! Hier ging es einfach darum mal ein Singleton zu bauen! Der Tipp das Singleton direkt über Member zu initialisieren passt gerade noch so zu dem Thread hier, alles andere ist mit Knanonen auf Spatzen schießen!
Du hast bestimmt dein erstes Hello World in Java mit Factorys gebaut - Gratulation!!!

bye Saxony


----------



## Wildcard (16. Jun 2008)

Es muss ja keine Factory sein. Wenn der OP es einfach und schnell und nicht OOP haben will, soll er doch statische Methoden machen, davon hält ihn doch keiner ab.
Die Frage ist, warum in aller Welt ein Singleton? Welchen rationalen Grund gibt es dafür? Es macht sogar mehr Arbeit als statische Methoden.


----------



## SlaterB (16. Jun 2008)

ein Objekt mit get, size und anderen Operationen und Variablen wie der HashMap statisch nachzubauen 
ist doch wohl sehr unnatürlich und sogar aus OOP-Sicht nicht empfehlenswert

zumal bei statischen Methoden die Vererbung wegfällt, wie hier in diesem Thread gerade benötigt
(natürlich unter der Prämisse dass es hier wahrscheinlich drei Objekte der gleichen Klasse auch tun,
aber selbst dann bräuchte man Objekte, statische Operationen will niemand 3x schreiben..)

> warum in aller Welt ein Singleton? Welchen rationalen Grund gibt es dafür? Es macht sogar mehr Arbeit als statische Methoden.

statisch fällt also weg, alles in Java ist normal ein Objekt,
Verhinderung mehrerer Objekte geht nur per Singleton, 
wobei natürlich nicht das Original-Singleton gemeint ist, denn das wäre ja völlig falsch benannt/ eingesetzt 

ich hätte es nicht besser formulieren können:


			
				mad-din hat gesagt.:
			
		

> Wildcard hat gesagt.:
> 
> 
> 
> ...


----------



## Guest (16. Jun 2008)

SlaterB hat gesagt.:
			
		

> private Konstruktoren und bestimmte abstrakte Klassen in Java sind Schwachsinn? gut zu wissen


Der Konstruktor der Math-Klasse ist private. Macht das Sinn? Kann man sich drüber streiten. Ich persönlich finde es schwachsinnig, weil ich niemals auf die Idee käme, ein Exemplar von Math zu erstellen. Es würde ja auch nichts schlimmes passieren, wenn es jemand täte.

Eine abstrakte Klasse ist etwas anderes als eine Klasse. Eine abstrakte Klasse ist nicht als Blaupause für Exemplare gedacht, im Gegensatz zu einer Klasse. Die Tatsache, dass man eine abstrakte Klasse nicht instanziieren kann, hat mit dem Zweck ebensolcher zu tun (gemeinsamen Code mehrerer ähnlicher konkreter Klassen hochziehen).
Außerdem beinhalten die meisten abstrakten Klassen abstrakte Methoden, und das Typsystem von Java darf eine Instanziierung einer solchen abstrakten Klasse auf gar keinen Fall erlauben. Aber Du meinst wahrscheinlich abstrakte Klassen ohne abstrakte Methoden, oder?



> > - Eine Klasse sollte nicht verbieten, dass man Exemplare von ihr erstellt.
> 
> 
> ich wünschte es gäbe dafür auch mal eine Begründung,


Schlag mal in Betrand Meyers Buch unter "Composability" nach.



> aus reinen Spass, einen OO-Buch blind gefolgt zu sein


Das ist wohl das Hauptproblem. Man liest etwas in einem OO-Buch, versteht es nicht, denkt aber, es sei cool, und man baut es nach, auch wenn es für das eigene Problem völlig ungeeignet ist.



> > - Global verfügbare Objekte haben maximale Kopplung (JEDER kann darauf zugreifen) und sind daher sehr schlecht testbar.
> 
> 
> das System.out-Argument


System.out ist ein Stream und damit eine ganz andere Schiene. Es ist ja nicht so, dass gewisse Module sich darauf verlassen, dass niemand anders den Stream anpackt. Man schiebt ja bloß Ausgaben auf den Stream. Eine Klasse wird nicht völlig unvorhersehbar reagieren, wenn eine andere Klasse zwischendurch eigene Ausgaben auf den Stream leitet. Das liegt daran, dass niemand sondierende Operationen auf Ausgabeströmen aufruft. Gibt es überhaupt welche?

Davon ab: in keinem meiner Projekte wird System.out in mehr als zwei, drei Modulen verwendet, wenn überhaupt. Bei GUI-Programmen überhaupt nicht mehr.



			
				Saxony hat gesagt.:
			
		

> wieso sollte ich bei einem 3-5 Klassen Programm noch zusätzlich Factory bzw. Builder Klassen schreiben, nur weil ich mal eine meiner Klasse nur einmal erstellen will?


Und wieso solltest Du ausgerechnet ein Singleton einsetzen, "nur weil Du eine Deiner Klassen nur einmal erstellen willst"?
Sieh Dir mal folgendes "Pattern" an, genau so erzeugt man ein Exemplar einer Klasse:

```
public class X
{
	// ...
}

class Main
{
	public static void main(String[] args)
	{
		X x = new X(); // ein Exemplar erstellen
	}
}
```

Sehr viel umständlicher ist dagegen das Singleton, welches wir gar nicht benötigen:

```
public class X
{
	private static X instance;

	private X()
	{
		// ...
	}

	public static synchronized X getInstance()
	{
		if (instance == null)
			instance = new X();
		return instance;
	}

	// ...
}

class Main
{
	public static void main(String[] args)
	{
		X x = X.getInstance();
	}
}
```

Das schöne am ersten "Pattern" ist, dass Du später auch beliebig viele weitere Exemplare erstellen kannst. Der Fragesteller braucht ja z.B. drei Stück:

```
public class X
{
	// ...
}

class Main
{
	public static void main(String[] args)
	{
		X x = new X(); // ein Exemplar erstellen
		X y = new X(); // ein zweites Exemplar erstellen
		X z = new X(); // ein drittes Exemplar erstellen
	}
}
```

Das kann das Singleton nicht leisten. Anstatt diese einfache Lösung zu verwenden, will der Fragesteller aber unbedingt beim Singleton bleiben und schlägt sowas vor:

```
public class X
{
	private static X instance;

	private X()
	{
		// ...
	}

	public static synchronized X getInstance()
	{
		if (instance == null)
			instance = new X();
		return instance;
	}

	// ...
}

public class Y
{
	private static Y instance;

	private Y()
	{
		// ...
	}

	public static synchronized Y getInstance()
	{
		if (instance == null)
			instance = new Y();
		return instance;
	}

	// ...
}

public class Z
{
	private static Z instance;

	private Z()
	{
		// ...
	}

	public static synchronized Z getInstance()
	{
		if (instance == null)
			instance = new Z();
		return instance;
	}

	// ...
}

class Main
{
	public static void main(String[] args)
	{
		X x = X.getInstance();
		Y y = Y.getInstance();
		Z z = Z.getInstance();
	}
}
```

Wenn er später merkt, dass er irgendwo einen Fehler gemacht hat, dann muss er diesen in drei Klassen korrigieren. Ist das schön? Ist das einfach? Ist das objektorientiert? Ganz sicher nicht.
Woher kommt bloß dieser starke Drang, unbedingt das Singleton einsetzen zu wollen? Ich verstehe es einfach nicht.

Just say NO to singletons. They are evil.


----------



## SlaterB (16. Jun 2008)

Anonymous hat gesagt.:
			
		

> Aber Du meinst wahrscheinlich abstrakte Klassen ohne abstrakte Methoden, oder?


genau, 'bestimmte' abstrakte Klassen



> Schlag mal in Betrand Meyers Buch unter "Composability" nach.


hmm, das ist ja wenig überzeugend (nicht was im Buch steht sondern dieser Hinweis),
klingt höchstens nach
- es steht in einer Bibel also ist es gut
- vermutlich wird auf 500 Seiten Design zu 500 Klassen-Programmen beschrieben

beides eher unnütz im einfachen Falle



> > aus reinen Spass, einen OO-Buch blind gefolgt zu sein
> 
> 
> Das ist wohl das Hauptproblem. Man liest etwas in einem OO-Buch, versteht es nicht, denkt aber, es sei cool, und man baut es nach, auch wenn es für das eigene Problem völlig ungeeignet ist.


passt ja gut, du meinst damit sicherlich den falschen Einsatz des Singletons,
ich könnte damit genauso deine Argumente dagegen beschreiben




> System.out ist ein Stream und damit eine ganz andere Schiene. Es ist ja nicht so, dass gewisse Module sich darauf verlassen, dass niemand anders den Stream anpackt. Man schiebt ja bloß Ausgaben auf den Stream. Eine Klasse wird nicht völlig unvorhersehbar reagieren, wenn eine andere Klasse zwischendurch eigene Ausgaben auf den Stream leitet.


genau das gleiche gilt auch für das Singleton hier bzw. für alle derartigen, über die ich hier rede, 
deswegen passt ja der Vergleich,

in einfachen Programmen passieren keine unvorhersehbaren Dinge, 
es geht vornehmlich darum, Objekte nicht unnötig doppelt zu erstellen und mühsam Variablen durchzureichen




> Sieh Dir mal folgendes "Pattern" an, genau so erzeugt man ein Exemplar einer Klasse:
> [..]


wieso sollte sich durch neues Ansehen irgendwas verändern, welchen verfälschten Blick könnte man vorher haben?
das X-Objekt in der main ist nur eines, nun muss man es noch überall im Programm verteilen
(besonders nett bei 3-4 solcher Objekte, wobei man allerdings den Vorteil hat, ein Sammelobjekt zu erstellen)
und es können Duplikate erstellt werden



> Sehr viel umständlicher ist dagegen das Singleton, welches wir gar nicht benötigen:
> [..]


das getInstance() meist ohne Funktion ist wurde ja nun hinlänglich besprochen, nach gewisser Zeit merkt das auch jeder Anfänger, 
spätestens durch gute Tipps im Forum

bleibt also ein private statt public und eine Zeile für die statische Variable, wow, eine Zeile mehr Code..





> Das schöne am ersten "Pattern" ist, dass Du später auch beliebig viele weitere Exemplare erstellen kannst. Der Fragesteller braucht ja z.B. drei Stück:
> 
> ```
> public class X
> ...




hier wirst du nun aber unfair, drei gleiche Objekte sind ja nun ganz gewiss nicht gefragt,
es brächte auf jeden Fall drei unterschiedliche Lade-Operationen und man müsste


```
X x = new X(); // ein Exemplar erstellen
x.ladeDaten1();
X y = new X(); // ein zweites Exemplar erstellen
y.ladeDaten2();
X z = new X(); // ein drittes Exemplar erstellen
z.ladeDaten3();
```
aufrufen, Operationen die man verwechseln kann, die auch später noch bei allen drei Objekten durcheinander sichtbar sind usw.,
nicht schön,
dazu weiter das Übergabe-Problem + weitere Objekte erstellbar

solange sich die Objekte nicht auch durch bestimmtes Verhalten unterscheiden
bleibts natürlich dabei, dass in diesem Falle eine Klasse wahrscheinlich besser ist, aber selbst hier ist das offen
und im Normalfall hat man ja nicht diese 3 Objekte, 
n != 1 wie gesagt



> Wenn er später merkt, dass er irgendwo einen Fehler gemacht hat, dann muss er diesen in drei Klassen korrigieren.
> Ist das schön? Ist das einfach? Ist das objektorientiert? Ganz sicher nicht.


du darst auch nicht alles überlesen, es ging doch gerade von Anfang an in diesem Thread darum,
eine gemeinsame Basisklasse zu definieren um die Codeverdreifachung zu vermeiden,
ganz so unausgeschlafen ist auch hier keiner



> Woher kommt bloß dieser starke Drang, unbedingt das Singleton einsetzen zu wollen? Ich verstehe es einfach nicht.


einfach, komfortabel, fehlervermeidend, perfekt,
schon bevor jemand das als Pattern patentierte oder gar als Evil deklarierte, ein universelles Programmierkonzept


----------



## Guest (16. Jun 2008)

SlaterB hat gesagt.:
			
		

> > Woher kommt bloß dieser starke Drang, unbedingt das Singleton einsetzen zu wollen? Ich verstehe es einfach nicht.
> 
> 
> einfach, komfortabel, fehlervermeidend, perfekt


Es sieht so aus, als kämen wir auf keinen gemeinsamen Nenner. Ich bleibe bei meinem Standpunkt, dass man in einem ordentlichen OO-Design kein Singleton braucht und es früher oder später nur zu Problemen führt, und Du bleibst bei Deinem Standpunkt, dass es einfach und praktisch ist. Jede Partei hat ihre Argumente vorgebracht, und weitere Diskussion scheint nicht mehr viel zu bringen.


----------



## Niki (16. Jun 2008)

Ohne jetzt alle Antworten durchgelesen zu haben, aber was spricht dagegen eine Factory einzusetzen, die eine Instanz der konkreten Klasse zurück liefert. Die konkreten Klassen haben eine gemeinsame, abstrakte Basisklasse und nur im Detail unterscheiden sie sich. Die Factory liefert dann halt immer die gleiche Instanz dieser Klasse zurück. Wenn die Factory und die Klassen im selben Package liegen, kann man den Zugriff der Klassen auf package setzen. Wenn man dann immer über die Factory die Objekte holt existiert immer nur eine Instanz einer Klasse. Das ganze halt mal drei. Also ca. so:

```
public abstract class BasisKlasse{

  private Map map = null;

  public BasisKlasse(){
    map = load();
  }

  public Object getValue(Object key){
    return map.get(key);
  }

  public abstract Map load();
}
```


```
public class MyImpl1 extends BasisKlasse{

  public Map load(){
    Map m = new HashMap();
    m.put("1", "duh");
    return m;
  }

}
```


```
public class MyImpl2 extends BasisKlasse{

  public Map load(){
    Map m = new HashMap();
    m.put("2", "duh2");
    return m;
  }

}
```


```
//Die könnte ja auch Singleton sein
public class MyFactory{

  private static MyFactory intance = null;

  private MyImpl1 myImpl1 = null;

  private MyImpl2 myImpl2 = null;

  public static synchronized MyFactory getInstance(){
    if(instance == null){
      instance = new MyFactory();
    }
    return instance;
  }

  public BasisKlasse getBasisKlasse(int typ){
    switch(typ){
      case 0 : if(myImpl1 == null) myImpl1 = new MyImpl1(); return myImpl1;
      case 1 : if(myImpl2 == null) myImpl2 = new MyImpl2(); return myImpl2;
    }
    return null;
  }
}
```


```
BasisKlasse bk = MyFactory.getInstance().getBasisKlasse(0);
```


----------



## SlaterB (16. Jun 2008)

dagegen spricht nichts, außer dass es (je nach Codegefühl) unnötig komplizierter ist,

selbst wenn man die Factory einsetzt kann man ja auf diese 0, 1 usw. verzichten
und drei einfache getter schreiber, wieder je nachdem wie es einem beliebt

--------

dass du aus der Factory ein Singleton machst, gar mit getInstance(),
ist ja ein geradezu paradoxer Scherz, 
dann hast du wirklich nicht viel von der Diskussion gelesen


----------



## Niki (16. Jun 2008)

Da geb ich dir recht. Ich hab nur irgendwo überflogen dass es ein Singleton sein muss. Glaub ich zumindest. Ich würd die Factory selber nicht als Singleton machen. Eventuell statisch die Methoden für die einzelnen Instanzen anbieten. Das würde mehr Sinn machen.


----------



## byte (16. Jun 2008)

Singleton = Antipattern

Fast immer wird das Pattern mißbraucht, weil man zu faul ist, Objekte korrekt zu initialisieren. Spätestens in einem größeren, stark modularisierten Projekt (= viele Java-Projekte / Osgi-Bundles mit Abhängigkeiten), fliegt einem so ein Spagetticode aber um die Ohren.

Klar kann man  in Mini-Programmen, bestehend aus ner Handvoll Klassen, fix mal ein paar Singletons schreiben. Genauso könte man auch alle Methoden statisch machen.

Man kanns aber auch gleich richtig machen, anstatt sich einen schlechten Stil anzugewöhnen. Das Ganze Thema wird obsolet, wenn man sich mal mit Dependency Injection beschäftigt hat.


Edit: 
Wenn ich keine Abhängigkeit zu einem Container oder Framework mit DI haben möchte, mache ich folgenden Kompromiss: Ich definiere ein Context-Objekt als Singleton. Dieses wird einmalig beim Starten der Anwendung initialisiert und steht anderen Objekten per getInstance() zur Verfügung. Dieses Context-Objekt bietet Zugriff auf alle weiteren "Singleton"-Objekte und verwaltet diese.


----------



## Wildcard (16. Jun 2008)

byto hat gesagt.:
			
		

> Wenn ich keine Abhängigkeit zu einem Container oder Framework mit DI haben möchte, mache ich folgenden Kompromiss: Ich definiere mit ein Context-Objekt als Singleton. Dieses wird einmalig beim Starten der Anwendung initialisiert und steht anderen Objekten per getInstance() zur Verfügung. Dieses Context-Objekt verwaltet alle weiteren "Singleton"-Objekte.


Bei mir ist es ähnlich. Verschiedene OSGi Bundles die jeweils tatsächlich nur einmal existieren dürfen. Der Activator hat eine statische Zugriffsmethode auf eine Instanz seiner selbst und gewährt damit Zugriff auf den BundleContext aus dem man sich seine Services geben lässt.


----------

