856 Stimmen

Wie kann man ein Singleton-Muster in Java effizient implementieren?

Wie lässt sich ein Singleton-Entwurfsmuster in Java effizient implementieren?

2voto

raoadnan Punkte 293

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.

2voto

user3792852 Punkte 181

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.

1voto

rohan kamat Punkte 563

Einfachste Singleton-Klasse:

public class Singleton {
  private static Singleton singleInstance = new Singleton();
  private Singleton() {}
  public static Singleton getSingleInstance() {
    return singleInstance;
  }
}

0voto

shikjohari Punkte 2170

Ich bin immer noch der Meinung, dass enum nach Java 1.5 die beste verfügbare Singleton-Implementierung ist, da sie auch in Umgebungen mit mehreren Threads sicherstellt, dass nur eine Instanz erstellt wird.

public enum Singleton {
    INSTANCE;
}

Und schon sind Sie fertig!

0voto

kenju Punkte 5476

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.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X