Wie lässt sich ein Singleton-Entwurfsmuster in Java effizient implementieren?
Antworten
Zu viele Anzeigen?Für JSE 5.0 und höher sollten Sie den Enum-Ansatz wählen. Andernfalls verwenden Sie den Ansatz des statischen Singleton-Inhabers (ein von Bill Pugh beschriebener Ansatz für "Lazy Loading"). Die letztgenannte Lösung ist auch thread-sicher, ohne dass spezielle Sprachkonstrukte (d.h. volatile oder synchronized) erforderlich sind.
Ein weiteres Argument, das häufig gegen Singletons ins Feld geführt wird, ist ihre mangelnde Testbarkeit. Singletons sind zu Testzwecken nicht leicht zu spiegeln. Wenn sich dies als Problem herausstellt, nehme ich gerne die folgende leichte Änderung vor:
public class SingletonImpl {
private static SingletonImpl instance;
public static SingletonImpl getInstance() {
if (instance == null) {
instance = new SingletonImpl();
}
return instance;
}
public static void setInstance(SingletonImpl impl) {
instance = impl;
}
public void a() {
System.out.println("Default Method");
}
}
Der Zusatz setInstance
Methode ermöglicht es, während des Testens eine Mockup-Implementierung der Singleton-Klasse zu erstellen:
public class SingletonMock extends SingletonImpl {
@Override
public void a() {
System.out.println("Mock Method");
}
}
Dies funktioniert auch mit frühen Initialisierungsansätzen:
public class SingletonImpl {
private static final SingletonImpl instance = new SingletonImpl();
private static SingletonImpl alt;
public static void setInstance(SingletonImpl inst) {
alt = inst;
}
public static SingletonImpl getInstance() {
if (alt != null) {
return alt;
}
return instance;
}
public void a() {
System.out.println("Default Method");
}
}
public class SingletonMock extends SingletonImpl {
@Override
public void a() {
System.out.println("Mock Method");
}
}
Dies hat den Nachteil, dass diese Funktionalität auch für die normale Anwendung zur Verfügung steht. Andere Entwickler, die an diesem Code arbeiten, könnten versucht sein, die "setInstance"-Methode zu verwenden, um eine bestimmte Funktion zu ändern und damit das gesamte Verhalten der Anwendung zu verändern. Daher sollte diese Methode zumindest eine deutliche Warnung in der Javadoc enthalten.
Für die Möglichkeit von Mockup-Tests (falls erforderlich) kann diese Code-Exposition jedoch ein akzeptabler Preis sein.
Werfen Sie einen Blick auf diesen Beitrag.
Beispiele für GoF-Entwurfsmuster in den Kernbibliotheken von Java
Aus dem Abschnitt "Singleton" der besten Antwort,
Singleton (erkennbar an Erstellungsmethoden, die immer dieselbe Instanz (normalerweise von sich selbst) zurückgeben)
- java.lang.Runtime#getRuntime()
- java.awt.Desktop#getDesktop()
- java.lang.System#getSecurityManager()
Sie können das Beispiel von Singleton auch aus den nativen Java-Klassen selbst lernen.