Singleton

Sichere ab, dass eine Klasse genau eine Instanz besitzt, und stelle einen globalen Zugriffspunkt darauf bereit.

Erweiterung

Das Klassendiagramm für das Entwurfsmuster Singleton

Ein Singleton ist von Natur aus nicht erweiterbar. Soll diese Eigenschaft dennoch benötigt werden, muss der Konstruktor protected gesetzt werden und jede abgeleitete Singletonklasse muss ebenfalls eine getInstance()-Methode besitzen. Durch die Referenzierung einer der Klassen in der Singletonhierarchie, kann dann das gewünschte Singleton ausgewählt werden. Die abgeleiteten Singletons sollten, wie immer bei Vererbung, Funktionalität lediglich nur hinzufügen, nicht ändern oder gar entfernen.

Implementierung in C++

In der folgenden Beispielimplementierung wird sichergestellt, dass das Singleton beim Beenden der Applikation ordnungsgemäß entsorgt wird. Da neben dem Konstruktor auch der Destruktor als private deklariert ist, kann das Singleton erwartungsgemäß von außen weder angelegt noch zerstört werden. Die Singletonklasse hält hier nicht die Instanz auf sich selbst, sondern die Instanz einer Verwaltungsklasse. Der Destruktor der Verwaltungsklasse sorgt für die Entsorgung des Singletonobjekts bei Programmende.

//////////////
// singleton.h
class Singleton
{
	struct Manager
	{
		Singleton* instance;
		~Manager()
		{
			delete instance;
		}
	};

public:
	static Singleton* getInstance();

private:
	static Manager manager;

	Singleton() { /* Initialisieren */ }
	~Singleton() { /* Aufräumen */ }
};

///////////////
//singleton.cpp
Singleton::Manager Singleton::manager;
 
Singleton* Singleton::getInstance()
{
	if (manager.instance == 0)
		manager.instance = new Singleton();
	return manager.instance;
}

Implementierung in C++

Diese Implementierung ist angelehnt an das Buch C++ Einstieg für Anspruchsvolle, André Willms, Addison-Wesley, 2005.

Implementierung in Java

Die Implementierung des Singleton in Java sieht ähnlich dem in C++ aus, hier ist jedoch Manager-Klasse nicht erforderlich. Es kann jedoch zu Nebeneffekten kommen, wenn die getInstance()-Methode in verschiedenen Threads gleichzeitig aufgerufen werden, z. B. kann dabei das Singleton mehrfach initialisiert werden. Der naive Ansatz wäre es getInstance() zu synchronisieren. Dies erzeugt jedoch eigentlich unnötigen Overhead beim Kompilieren der Klasse.

Eleganter ist es, den statischen Member direkt bei der Deklaration zu initialisieren. Da diese Initialisierung erst geschieht, wenn der Classloader die Klasse lädt, ist diese Implementierung immer noch Lazy. Der statische Member kann nun sogar public final deklariert werden. Das Eclipse Modelling Framework (EMF) nutzt bspw. diese Variante des Singletons.

Folgendes Beispiel demonstriert diese Singletonvariante:

class Singleton {

	public static final Singleton INSTANCE = new Singleton();

	private Singleton() { /* Initialisieren */ }

}

Zurück