The Singleton Pattern in Java

Es gibt einige Möglichkeiten wie das Singleton Pattern in Java umzusetzen ist. Hier möchte ich einen kurzen Überblick über diese geben und einige Stärken bzw. Schwächen aufdecken.

a synchronized method

Eine der verbreitetsten Methoden das Singleton Pattern  zu implementieren, listet unter anderem auch Wikipedia als Java Referenz dafür. Durch einen privaten Konstruktor wird der Zugriff von außen vermieden, die einzige Instanz in einer private static Variable abgelegt. Über eine synchronisierte Methode erhält man Zugriff auf diese Variable. Ist die Instanz noch nicht erzeugt worden wird dies nachgeholt, anstonsten die bereits abgelegte retourniert. Der Nachteil dieser Variante ist durch seinen Thread sicheren Zugriff gegegeben. Damit, dass die Instanz nur durch eine synchronisierte Methode aufrufbar ist, blockieren sich mehrere Threads die darauf zugreifen wollen gegenseitig.

public class Singleton {

	/* Privates Klassenattribut, welches beim ersten Laden erzeugt wird. */
	private static Singleton instance;

	/* Privater Konstruktor um Zugriff von außen zu verhindern */
	private Singleton() {}

	/* Statische Methode liefert die einzige Instanz der Klasse zurück */
	public synchronized static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

a public final field

Um die Problematik der synchronisierten Zugriffe zu umgehen, muss das Objekt früher erzeugt werden und nicht erst bei Zugriff auf eine Methode der Klasse. Dazu wird z.B. ein public static final Field genutzt, auf das zugegriffen werden kann. Dieses wird bei Initialisierung der Klasse befüllt und kann dannach nicht mehr verändert werden. Wermutstropfen: über Reflektion kann man dennoch auf den privaten Konstruktor zurückgreifen.

public class Singleton {

	/* Instanzierung von Singleton */
	public static final Singleton INSTANCE = new Singleton();

	/* Privater Konstruktor um Zugriff von außen zu verhindern */
	private Singleton() {}
}

a private final field accessable by a public method

Eine Vermischung beider Varianten ist folgendes Beispiel

public class Singleton {

	/* Instanzierung von Singleton */
	private static final Singleton INSTANCE = new Singleton();

	/* Privater Konstruktor um Zugriff von außen zu verhindern */
	private Singleton() {}

	/* Methode zum Zugriff auf die Instanz */
	public static Singleton getInstance(){
		return INSTANCE;
	}
}

Vermeidet die Mängel der ersten Methode, offeriert aber den selben Schwachpunkt wie die zweite hier genannten Methode. Gemeinsam mit der zeiten Methode, dem public final Field, sind diese beiden Ansätze der Ersten jedoch vorzuziehen, da bei ihnen durch das Feld eindeutig hervorgeht, dass es sich um ein Singleton handelt. Das final Field wird immer das selbe Objekt referenzieren. Ist noch zusätzlich eine Methode vorhanden um auf das final Field zuzugreifen erhält man einen weiterne Vorteil. Man kann das Konzept des Singletons wieder aufgeben ohne die API ändern zu müssen. Der Client kann damit weiter über die getInstance Methode eine Instanz erhalten.

a singleton by enum

Seit Java 1.5 ist eine weitere Möglichkeit entstanden. Ein Enum mit nur einem einzigen Element:

public enum Singleton{
	INSTANCE;
}

Dieser Ansatz ist serialisierbar, kurz gehalten, sicher vor Mehrfachinstanzierung und vereint die Vorteile der vorher angesprochenen Ansätze. Dieser Weg ist der empfohlene Weg und sollte zukünftig gegangen werden.

Weitere Literatur

[1] Singleton Pattern auf Wikipedia

[2] Design Patterns Head First

[3] Entwurfsmuster GoF

Ähnliche Artikel: