Design Patterns: Singleton
Oftmals ist es nicht schwer, ein kleines Stück Software oder ein gutes Tool zu entwickeln. Doch was tun, wenn man ein wesentlich größeres und aufwendigeres Projekt realisieren möchte. Ich stand auch schon häufig vor diesem “Problem”, da ich häufig keinen passenden Anfang finde. Wenn das Grundkonzept steht möchte man viel zu oft schnell ans Programmieren. Generell auch eine feine Sache, die von Enthuisasmus zeugt. Aber Vorsicht! Klassen einfach drauf los zu programmieren ist eine Todsünde!
Es ist zwangsläufig notwendig, sich vorher mit seinen Klassen auseinander zu setzen, um nicht später alles über den Haufen werfen zu müssen, wenn man merkt, dass man etwas wichtiges vergessen hat. In diesem Prozess sind sogenannte Design Patterns von absoluter Notwendigkeit! Diese Entwicklungs Muster dienen dazu, grundsätzliche Strukturen und Verfahren in Euer Programm zu bringen. Ich möchte mich im ersten Teil dieser Serie mit dem Singleton, also der Einmal-Instanzierung einer Klasse, beschäftigen.
Fängt man ein neues Projekt an, so hat man meistens einen Basis-Layer, der die Verbindungungen mit Datenbanken reglementiert (Database Access Layer [DAL]) oder Konfigurationen aus einer XML oder anderen Formaten ausliest. Gerade beim DAL ist es von bedeutender Relevanz, dass pro Anwendung nur eine einzige DAL-Initiierung erfolgen darf! Man möchte schließlich nicht 3 oder 4 Mal die gleiche Datenbank mit unterschiedlichen Objekten, mit vielleicht sogar unterschiedlichen Parametern ansprechen.
Der Design Pattern “Singleton” reglementiert die Instanzierung von Klassen. Dabei ist die theoretische Vorgehensweise sehr einfach. Wichtig ist zuersteinmal, dass wir den Konstruktor von außen nicht mehr zugänglich machen. Dieser ist nun private und kann nur vom Singleton aufgerufen werden. Soweit, so gut. Nun müssen wir uns überlegen, wie wir prüfen können, ob es bereits eine Instanz unserer Klasse gibt. Das machen wir indem wir in der Klasse eine Variable vom Typ der zu überwachenden Klasse anlegen und auf NULL setzen.
Der Singleton
private static volatile Klassenname _instance = null; private static object m_lock = new object(); public static Klassenname GetInstance() { if (_instance == null) { lock(m_lock) { if (_instance == null) { _instance = new Klassenname(); } } } return _instance; }
Diese Methodik bezeichnet auch schon den Singleton. Wir prüfen, ob eine Instanz der Klasse angelegt wurde. Ist dies nicht der Fall, sperren wir den folgenden Code für weitere Threads, die eventuell auf diese Klasse zugreifen könnten und prüfen erneut, ob eine Instanz vorliegt (DoubleLock). Ist dies nun immernoch nicht der Fall, so erzeugen wir eine neue Instanz, rufen also den Konstruktor auf.
Nun wurde die Variable _instance auf die gerade erzeugte Instanz festgelegt und kann bei jedem weiteren Aufruf von GetInstance() an das Objekt vom Typen Klassenname zurückgegeben werden. Doch wofür das alles? Ganz einfach: Wir brauchen keine Objekte mehr zwischen mehreren Klassen hin und her zu übergeben. Diese Klassen können nun mit GetInstance() einfach der vollständig initialisierte Klasse holen und mit all ihren Werten und Parametern arbeiten.
GetInstance() im Einsatz
// Aufruf der Klassen-Instanz Klassenname myClass = Klassenname.GetInstance(); // Aufruf mit Hilfe eines Interfaces IKlassenname myClass = Klassenname.GetInstance();
Diese Vorgehensweise lässt sich auch ideal erweitern, falls Ihr nur eine gewisse Anzahl an Instanzen zulassen wollte. Sowas kann gebraucht werden, wenn man Zugriff auf mehr als eine Datenbank haben möchte. In diesem Fall kann man dem Singleton noch Parameter übergeben, welche er dazu nutzen kann, ebenfalls den Konstruktor parameterisiert aufzurufen. Probiert es aus, Euch sind so gut wie keine Grenzen gesetzt!
Leave a comment
