Entwurfsmuster (Design Patterns)
Beim Programmieren stellt man fest, dass bestimmte Schemata sich oft wiederholen (meist mit geringen Unterschieden) - diese Schemata bzw. Muster nennt man Entwurfsmuster (Design Patterns).
Entwurfsmuster beschreiben die Kommunikation von Objekten in einer Art die einem eine flexibel und leicht erweiterbare Software Architektur gewährleistet. Sie helfen einem beim Entwickeln bzw. Entwerfen eines gültigen Systems.
Viele Entwurfsmuster wurden über die Jahre dokumentiert und sollen hier nun vorgestellt werden. Hier werden die wichtigsten Entwurfsmuster vorgestellt, wie sie zu verwenden sind und warum man sie nutzen sollte.
Hierbei möchte ich doch darauf hinweisen, dass diese Auflistung nur eine kleine Auswahl sein kann und auch nicht auf jedes Pattern in Tiefe eingegangen wird (z.B. Sinn & Unsinn eines Patterns) - dafür sollte dann die Literatur zu Rate gezogen werden.
Es werden auch keine J2EE Patterns vorgestellt... über die gibt es [hier] eine gute Übersicht.
Inhaltsverzeichnis
Singleton
Das Singleton Pattern stellt sicher, dass es von einer Klasse nur eine Instanz gibt.
Oft verwendete Beispiele sind Datenbankmanager Klassen (um nicht in den Konflikt zu kommen mehrer DB Connections handeln zu müssen o.ä.) oder eine Configurations Klasse, die für mehrere Klassen in der Anwendung wichtige Informationen bereit stellt.
Um ein Singleton zu erstellen, gibt es zwei Möglichkeiten: <code=java>public class Singleton {
public static final Singleton instance = new Singleton();
private Singleton() { }
}</code=java>
<code=java>public class Singleton {
private static final Singleton instance = new Singleton(); private Singleton() { }
public static Singleton getInstance() { return instance; }
}
</code=java>
In beiden Fällen ist der private Konstruktor wichtig, der verhindert, dass die Klasse von außerhalb instanziiert werden kann. Beide Versionen unterscheiden nur in der static final
Variable. Deklariert man sie als private
, muss eine public
Methode gegegeben sein, um die Instanz zu erhalten. Ansonsten sind beide Versionen equivalent.
Der Vorteil der zweiten Version ist aber, dass man sie leicht abändern kann, wenn man z.b. nicht nur eine, sondern für jeden vorhandenen Thread eine eindeutige Instanz erzeugen will.
Oft sieht man auch folgende Variante: <code=java>public class Singleton {
private static Singleton instance; private Singleton() { }
public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; }
}</code=java>
Wichtig hierbei ist die Methode synchronized
zu definieren, so dass die Methode Thread sicher ist!
Eine Möglichkeit wäre, die Verwendung einer final
Klasse mit statischen Methoden (wie Math Klasse), diese Art behindert aber das Umschalten zwischen Singleton Klasse und "normaler" Klasse.
Anmerkung von Bleiglanz:
Die 1. und 2. Lösung sind für fast alle einfachen Fälle - das ist fast immer am besten (wobei die Variante mit getInstance zu bevorzugen ist).
die synchronized Lösung NUR DANN, wenn "lazy" Sinn macht [weil der Konstruktor "zu lange braucht"]
Auf das sog. Double Checked Locking sollte komplett verzichtet werden - siehe Double Checked Locking Is Broken