# Singleton Entwurfsmuster



## Sekundentakt (27. Jul 2010)

Hallo,

hier mal ein Singleton-Codeschnipsel von wikipedia.


```
public final class Singleton {
 
      /**
       * Privates Klassenattribut,
       * wird beim erstmaligen Gebrauch (nicht beim Laden) der Klasse erzeugt
       */
      private static Singleton instance;
 
      /** Konstruktor ist privat, Klasse darf nicht von außen instanziiert werden. */
      private Singleton() {}
 
      /**
       * Statische Methode „getInstance()“ liefert die einzige Instanz der Klasse zurück.
       * Ist synchronisiert und somit thread-sicher.
       */
      public synchronized static Singleton getInstance() {
          if (instance == null) {
              instance = new Singleton();
          }
          return instance;
      }
  }
```

Dieser Singleton hat den Nachteil, dass die getInstance()-Methode synchronisiert wird. Bei nebenläufigen Anwendungen, die alle auf den Singleton zugreifen wollen, könnte es daher zu Performanceproblemen kommen.

Schafft das hier Abhilfe?


```
public final class Singleton {
 
      /**
       * Privates Klassenattribut,
       * wird beim erstmaligen Gebrauch (nicht beim Laden) der Klasse erzeugt
       */
      private static Singleton instance;
 
      /** Konstruktor ist privat, Klasse darf nicht von außen instanziiert werden. */
      private Singleton() {}
 
      /**
       * Statische Methode „getInstance()“ liefert die einzige Instanz der Klasse zurück.
       * Ist synchronisiert und somit thread-sicher.
       */
      public static Singleton getInstance() {
          if (instance == null) {
              instance = createNewInstance();
          }
          return instance;
      }

      public synchronized static Singleton createNewInstance()
      {
            return new Singleton();
      }
  }
```

Beste Grüße


----------



## SlaterB (27. Jul 2010)

da haben sich schon manche drüber Gedanken gemacht, gibt sogar einen Fachbegriff 'Double-checked locking',
siehe z.B.
Double-checked locking: Clever, but broken - JavaWorld
crazybob.org: Lazy Loading Singletons

was aber nicht unbedingt den aktuellsten Stand enthalten muss, erster Link anscheinend von 2001


----------



## Niki (27. Jul 2010)

dadurch ist nicht sicher gestellt dass tatsächlich nur ein objekt existiert, da die abfrage, ob instance null ist, nicht synchronisiert ist. das heißt es könnte, während das objekt erstellt wird, ein zweiter thread vor der synchronisierten methode warten

//eventuell wär das schlauer: 
	
	
	
	





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


----------



## tfa (27. Jul 2010)

Ja, das ist Double-Checked-Locking. Siehe hier: Double-checked locking - Wikipedia, the free encyclopedia
Ab Java 1.5 gibt es eine funktionierende Lösung hierfür (siehe Artikel).

Trotzdem ist die Klasse aus Sekundentakts Beispiel kein Singleton, da createNewInstance() public ist.

Als Geheimtipp noch die beste Lösung: Verwende keine Singletons!


----------



## maki (27. Jul 2010)

> Schafft das hier Abhilfe?


Nein.

Frage: Wozu eigentlich die Lazy-Init?
Warum nciht einfach:

```
private static Singleton instance = new Singleton();
```
.. und nun wieder zum üblichen Tenor: Singletons schaffen starke Kopplung zwischen den Klassen und sollten im allgemeinen vermieden werden.


----------



## Sekundentakt (27. Jul 2010)

Okay, vielleicht erst mal zu mir:
Ich bin gerade dabei ein etwas umfangreicheres Projekt im privaten Rahmen zu realisieren.
Dieses Projekt soll mein Einstieg in JavaEE werden.

Folgendes habe ich mir gedacht:
Ich habe mehrere Schichten in meiner Anwendung:

Die Kommunikationsschicht (Servlet, Server-Klasse).
Die Applikationsschicht, welche sich wiederum in kleinere Schichten unterteilen lässt.

Die Applikationsschicht wird dabei für die Kommunikationsschicht als ein einziges Objekt dargestellt, das MyApplicationContainer-Objekt.
Um den Begriff etwas aufzuschlüsseln: Ich nenne es Container, weil es die gesamte Applikation enthält.
Falls ich mich eines Tages dazu entscheide, die JavaEE-Anwendung, welche derzeit über Servlets arbeiten soll, in einer Desktop-Umgebung einzusetzen, brauche ich nur das Container-Objekt richtig zu initialisieren und habe sofort sämtliche Möglichkeiten meiner Anwendung in eine Desktop-Anwendung eingebettet.

Dieser ApplicationContainer soll einige Objekte enthalten, die wirklich nur einmalig auftauchen dürfen.
Das sind mehrere DataAccesObjekte, VerificationHandler, RequestHandler und ResponseWriter, aber auch bestimmte Caches.

Ich brauche jedes dieser Objekte tatsächlich nur ein einziges mal, da sie einen bestimmten logischen Bereich der Anwendung kapseln. Welche das sind, sagen die obigen Namen ja schon.

Ich könnte jedes dieser Objekte im Konstruktor des MyApplicationContainers erstellen. Dann kann ich mir sicher sein, dass es nur ein einziges mal existiert. 
Ich habe an anderer Stelle in diesem Forum aber den Hinweis bekommen, dass ich das via Singleton-Entwurfsmuster realisieren soll.

Denke ich hier vielleicht zu kompliziert?

Danke!


----------



## maki (27. Jul 2010)

> Denke ich hier vielleicht zu kompliziert?


Ja 

Nur weil Objekte von bestimmten Klassen nur einmal brauchst, muss man sie ja nicht so verhunzen (SCNR), einmal instanziieren reicht doch auch.
Dir geht es wohl eher um den Zugriff über getInstance(), und genau hier beginnen die Probleme: globale Variablen, abhängigkeiten zu statischen Methoden... JEE bietet hierfür bessere Methoden, mit oder ohne Spring.

Nebenbei, warum nicht an den offiziellen JEE Bezeichnungen für Schichten Orientieren?
Servlets gehören in die Presentationtier, nicht in die "kommunikationsschicht" (?), wenn du schon einsteigst in JEE, dann doch bitte auf der richtigen Seite


----------



## Sekundentakt (27. Jul 2010)

> Servlets gehören in die Presentationtier, nicht in die "kommunikationsschicht" (?), wenn du schon einsteigst in JEE, dann doch bitte auf der richtigen Seite


So langsam kriege ich das Gefühl, dass das Buch, welches ich dazu lese, Müll ist...



> Dir geht es wohl eher um den Zugriff über getInstance(), und genau hier beginnen die Probleme: globale Variablen, abhängigkeiten zu statischen Methoden... JEE bietet hierfür bessere Methoden, mit oder ohne Spring.


Mir ging es darum, dass ich sicherstellen will, dass der GC das Objekt nicht killt, obwohl es noch gebraucht wird.
Eigentlich *sollte* das nicht passieren, aber auf irgendeiner Seite wurde mal so etwas suggeriert.

Btw: Gibt's irgendetwas an der Architektur zu kritisieren?


----------



## maki (27. Jul 2010)

> Mir ging es darum, dass ich sicherstellen will, dass der GC das Objekt nicht killt, obwohl es noch gebraucht wird.


Solange es referenziert wird kann es nciht "gekillt" werden.



> Gibt's irgendetwas an der Architektur zu kritisieren?


BEstimmt, wenn du konkreter wirst mit deinen Beschreibungen


----------



## Sekundentakt (27. Jul 2010)

> Solange es referenziert wird kann es nciht "gekillt" werden.


Gut, ich dachte diese Wahrheit wäre irgendwo im JavaEE-Standard umgeschrieben worden.



> BEstimmt, wenn du konkreter wirst mit deinen Beschreibungen


Es wäre toll, wenn Du die ein oder andere Frage anbieten könntest, denn ansonsten würde ich Dir hier eine mehrseitige Beschreibung präsentieren. Ich weiß nicht, ob das in Deinem Sinne wäre .


----------



## maki (27. Jul 2010)

Architektur sollte immer schnell beschrieben werden können, geht ja nicht um Details, ganz grob eben, aus der Vogelperspektive.)
Design kann schon detailierter sein, sollte aber keine Implementierungsdetails enthalten 

Fragen:
Du nutzt ja DAOs, wo werden diese aufgerufen? -> Hoffentlich nicht in Servlets.
Wo steckt denn die Fachlogik der Anwendung? -> s.o.

Klassiche Architektur mit J(2)EE:
Servlets (Das C in MVC) -> EJBs (enthalten Fachlogik) -> DAOs -> DB

Servlet gehören zur Presentation Tier, EJBs zur Busniess Tier, DAOs zur Integration Tier.


----------



## Sekundentakt (27. Jul 2010)

Die Anwendung lässt sich so beschreiben:

- Servlet / Server / Desktopumgebung (Wer auch immer den Request entgegennimmt und im richtigen Format an die eigentliche Anwendung weitergibt)
- Anwendung
--- DAOs die auf DBs bzw. Dateien basieren

Also:
Servlet -> Anwendung -> DAOs -> DB/Datei

Frage:
Müssen sich EJBs an irgendetwas halten? Oder kann ich da wie ich lustig bin programmieren?

Das Servlet würde die Anwendung z.B. in Form einer Variable an sich binden.
Eine Desktop-Umgebung würde das an geeigneter Stelle ebenso tun.

EDIT;
Im Moment entwerfe ich Klassen für verschiedene Aufgaben (DAOs, VerifikationsHandler, RequestHandler, etc.). 
Die gesamte Logik soll sich dann im ApplicationContainer treffen (Request entgegennehmen, verifizieren, bearbeiten, ausführen, Ergebnis erstellen).

Ziel ist es, wie auch schon angedeutet, dass ich die gesamte Anwendung und all ihre Fähigkeiten in ein neues Projekt einbringen kann, ohne dem verantwortlichen Entwickler die Komplexität aller Schichten aufzuzwingen.

Wikipedia meint zu EJBs aber etwas, was irgendwie nicht zu meiner Beschreibung des ApplicationContainers passt.


----------



## maki (27. Jul 2010)

EJB2.x müssen sehr viel einhalten, EJB3.x nicht ganz soviel, ist aber nicht mal so auf die schnelle erklärt 

Dein Anwendungsschicht besteht auf Services nehme ich an, welche von den Servlets bzw. Desktop Client verwendet werden, ja?


----------



## Sekundentakt (27. Jul 2010)

Ich hab' das Ganze gerade eben noch etwas ergänzt.



> Dein Anwendungsschicht besteht auf Services nehme ich an, welche von den Servlets bzw. Desktop Client verwendet werden, ja?


Exakt.
Allerdings möchte ich dabei wie gesagt nicht voraussetzen, das meine Anwendung auf irgendeinem Server liegt, der via HTTP oder Ähnlichem angesprochen werden muss.
Ich möchte auch, dass man die Anwendung ganz einfach als Objekt in eine andere Anwendung einbetten kann.


----------



## maki (27. Jul 2010)

Vielleciht wäre SPring eher etwas für dich, spart dir auch die Singletons, ist imho flexibler weil universeller (obwohl EJB auch ganz schön leichtgewichtig sein kann), Spring ist läuft eben überall, von Desktop, WebApp, OSGi, Eclipse RCP bis hin zu JEE 

Allerdings ist Dependency Injection eine andere Art des Design (lose gekoppelte Komponenten - ja, Bullshit Bingo *G*), lohnt sich auf jedenfall DI zu erlernen, speziell weil EJB3 das auch hat und sehr gut zu deinen Anforderungen passt.


----------



## Sekundentakt (27. Jul 2010)

Danke für die Tipps .

Ich frage mal anders: Wenn ich all das *nicht* nutze, muss ich mir dann Gedanken darum machen, dass die Software *nicht* funktioniert? 

Ich bin ein bisschen darauf angewiesen, dass das was ich gerade mache am Tag X funktioniert. Es muss nicht perfekt sein, aber funktionieren. Es geht dabei um eine Präsentation, bei der ich gerne ein paar Algorithmen vorstellen würde und die ausführende Anwendung muss hier zwingend via Servlet erreichbar sein. 
Falls das was Du aufgezählt hast zwingend Pflicht ist, damit die Servlet-Anwendung läuft, seh ich da nämlich schwarz .

Gruß


----------



## maki (27. Jul 2010)

Pflicht ist es nciht, und wenn du einen Termin hast, dann geht es auch ohne (bzw. das würdest du schon merken), für Termine (vor allem Präsentationen) kannst du auch die Singletons drinnlassen.


----------



## Marco13 (27. Jul 2010)

Und wenn man keine Termine mehr anstehen, nimmt man sie raus. 
*prust*.


----------



## Sekundentakt (27. Jul 2010)

Ich bin zum Glück in der tollen Situation, dass ich die Singletons noch nicht mal implementiert hatte .

Es werden jetzt ganz normale Objekte, die im Konstruktor initialisiert werden.

Allerdings bin ich froh, dass ich vorher hier nachgefragt habe und nicht alles auf Singleton umgestellt habe.


----------



## Landei (27. Jul 2010)

Warum sollte man ein Singleton so schreiben wie oben? Wenn man wirklich eins haben will, geht es so am besten:


```
enum Singleton {
  INSTANCE;
  ...
}
```


----------



## bygones (28. Jul 2010)

Landei hat gesagt.:


> Warum sollte man ein Singleton so schreiben wie oben? Wenn man wirklich eins haben will, geht es so am besten:
> 
> 
> ```
> ...



richtig - wenn man eine Krankheit durch ein anderes Symptom leichter bekommt.... bygones


----------

