Alternative Implementierungen der Factory

Neben dem Factory Method und Abstract Factory Entwurfsmuster gibt es zwei alternative Implementierungen der Factory. Es sind die Simple Factory (einfache Fabrik) und die Static Factory Method (statische Fabrikmethode). Diese Implementierungen sind keine Entwurfsmuster, sondern eher Programmieridiome. Dennoch ist es wichtig sie zu kennen und zu wissen wann ihr Einsatz sinnvoll ist.

Um die Implementierung zu erläutern, greifen wir das Beispiel der Pizzeria wieder auf, welches bereits bei den Factory Entwurfsmustern verwendet wurde.

Weiterlesen

Das Abstract Factory-Muster

Definition

Das Abstract Factory-Muster (Abstrakte Fabrik) ist eines der GoFEntwurfsmuster (Design Pattern) und gehört zu der Kategorie der Erzeugungsmuster (Creational Design Pattern). Das Muster „bietet eine Schnittstelle zum Erstellen von Familien verwandter oder zusammenhängender Objekte an, ohne konkrete Klassen anzugeben“ (EvKbF S. 156).

Beschreibung

Das Abstract Factory-Muster ist mit dem Factory Method-Muster eng verwandt. Ebenso wie das Factory Method-Muster verwendet das Abstract Factory-Muster eine abstrakte Schnittstelle, um einen Satz verwandter Produkte zu erstellen, ohne die konkreten Produkte zu kennen. Das trägt ebenfalls zur Reduzierung der Abhängigkeiten, da der Client von den konkreten Produkten entkoppelt wird. Auch hier wird das folgende OO-Entwurfsprinzip angewendet:

„Stützen Sie sich auf Abstraktionen. Stützen Sie sich nicht auf konkrete Klassen.“
Das Abhängigkeits-Umkehrungs-Prinzip

Die Methoden in einer Abstrakten Fabrik, werden als Fabrikmethoden implementiert. Jede Methode ist dafür verantwortlich, ein konkretes Produkt zu erstellen. Dazu wird eine Unterklasse der Abstrakten Fabrik erstellt, in der die Implementierung der Methoden erfolgt, die ihrerseits die konkreten Produkte erzeugen. „Fabrikmethoden sind ein natürliches Mittel zur Implementierung von Produkt-Methoden in ihren abstrakten Fabriken.“ (EvKbF S. 158)

Weiterlesen

Das Factory Method-Muster

Definition

Das Factory Method-Muster (Fabrikmethode) ist eines der GoFEntwurfsmuster (Design Pattern) und gehört zu der Kategorie der Erzeugungsmuster (Creational Design Pattern). Das Muster „definiert eine Schnittstelle zur Erstellung eines Objekts, lässt aber die Unterklassen entscheiden, welche Klassen instanziert werden. Factory Method ermöglicht einer Klasse, die Instanzierung in Unterklassen zu verlagern“ (EvKbF S. 134).

Beschreibung

Eines der wesentlichen Merkmale der objektorientierten Programmierung sind die Beziehungen bzw. Abhängigkeiten zwischen den Objekten. Ein Entwurf mit vielen Abhängigkeiten kann jedoch sehr schnell unflexibel und schwer wartbar werden. Eine vollständige Vermeidung von Abhängigkeiten ist nicht möglich. Das Ziel sollte daher sein die Abhängigkeiten in einem Entwurf auf ein Minimum zu reduzieren. Durch die Anwendung des folgenden OO-Entwurfsprinzips, ist das Factory Method-Muster eine Hilfe dieses Ziel zu erreichen:

„Stützen Sie sich auf Abstraktionen. Stützen Sie sich nicht auf konkrete Klassen.“
Das Abhängigkeits-Umkehrungs-Prinzip

Die Verwendung von Abstraktionen verleiht einem Entwurf Flexibilität. Neue Anforderungen lassen sich schnell integrieren, ohne dass der bestehende Code geändert werden muss. Welche Rolle das Factory Method-Muster dabei spielt, beschreibt das Buch „Entwurfsmuster von Kopf bis Fuß“ auf der Seite 125, wie folgt:

Eine Factory Method-Fabrikmethode kümmert sich um die Objekt-Erstellung und kapselt sie in einer Unterklasse. Damit wird der Client-Code in der Superklasse vom Objekt-Erstellungscode in der Unterklasse entkoppelt.

  • Eine Fabrikmethode kümmert sich um die Objekt-Erstellung und kapselt sie in einer Unterklasse. Das entkoppelt den Client-Code in der Superklasse von der Objekt-Erstellung in der Unterklasse.
  • Eine Fabrikmethode liefert ein Produkt zurück, das üblicherweise innerhalb der Methoden verwendet wird, die in der Superklasse definiert werden.
  • Eine Fabrikmethode isoliert den Client (den Code in der Superklasse) so, dass er nicht wissen muss, welche konkrete Art von Produkt tatsächlich erstellt wird.
  • Eine Fabrikmethode kann so parametrisiert sein (oder nicht), dass sie unter verschiedenen Formen eines Produkts auswählt.

Die Kapselung der Objekt-Erstellung in einer Klasse bietet die Möglichkeit, diese in verschiedenen Clients wiederzuverwenden. Gleichzeitig hat man auch nur eine einzige Stelle, an der man Änderungen durchführen muss, sollte sich die Implementierung ändern.

Weiterlesen

Das Decorator-Muster

Definition

Das Decorator-Muster (Dekorierer) ist eines der GoFEntwurfsmuster (Design Pattern) und gehört zu der Kategorie der Strukturmuster (Structural Design Pattern). Das Muster „fügt einem Objekt dynamisch zusätzliche Verantwortlichkeiten hinzu. Dekorierer bieten eine flexible Alternative zur Ableitung von Unterklassen zum Zweck der Erweiterung der Funktionalität“ (EvKbF S. 91).

Beschreibung

Die Vererbung ist eines der grundlegenden Konzepte in der objektorientierten Programmierung. Jedoch sind auch diesem Konzept Grenzen gesetzt und seine Verwendung führt „nicht immer zu den flexibelsten oder wartbarsten Entwürfen“ (EvKbF S. 85). Eine überstrapazierte Verwendung der Vererbung kann zur Entstehung vieler Klassen führen und den Entwurf schließlich unübersichtlich werden lassen. Um diese Probleme zu vermeiden, verwendet das Decorator-Muster, ähnlich dem Strategy-Muster, die Komposition und Delegation um Verhalten „zu vererben“. Dabei setzt es auf eines der OO-Entwurfsprinzipien:

„Klassen sollten für Erweiterung offen, aber für Veränderungen geschlossen sein.“
Das Offen/Geschlossen-Prinzip

Das Decorator-Muster ermöglicht es das Verhalten einer Klasse dynamisch zu ändern. Dabei wird eine Klasse (Komponente), dessen Verhalten man erweitern will, von einer anderen Klasse (Dekorierer) dekoriert oder „umhüllt“. (Im englischen bedeutet „umhüllen“ „to wrap“. Daher auch der bekannte Begriff „Wraper-Klassen“.) Der Dekorierer verwendet die selbe Schnittstelle wie das zu dekorierende Objekt, womit er ebenso anstelle des eigentlichen Objekts verwendet werden kann. Dabei werden die Methodenaufrufe an die Komponente weiter delegiert und das eigene Verhalten davor oder danach ausgeführt.

Diese Methodik ermöglicht es bestehende Objekte um neue Funktionalitäten zu erweitern, indem man neuen Code schreibt, anstatt den vorhanden Code zu ändern. Dadurch sinkt die Gefahr erheblich unbeabsichtigte Fehler oder Nebeneffekte zu verursachen. Ebenso erreicht man auch einen Entwurf der flexibel genug ist neue Funktionalitäten aufzunehmen und den geänderten Anforderungen gerecht zu werden.

Weiterlesen

Das Observer-Muster

Definition

Das Observer-Muster (Beobachter) ist eines der GoFEntwurfsmuster (Design Pattern) und gehört zu der Kategorie der Verhaltensmuster (Behavioral Design Pattern). Das Muster „definiert eine Eins-zu-viele-Abhängigkeit zwischen Objekten in der Art, dass alle abhängigen Objekte benachrichtigt werden, wenn sich der Zustand des einen Objekts ändert“ (EvKbF S. 51).

Beschreibung

Die Interaktion der Objekte ist ein essentieller Bestandteil der objektorientierten Programmierung. Fälle, in denen bestimmte Objekte über Veränderungen in anderen Objekten informiert werden müssen, sind recht häufig. Das Ziel sollte daher ein Entwurf sein, in dem so viel wie möglich entkoppelt ist und die Abhängigkeiten reduziert sind. Das Observer-Muster setzt auf ein OO-Entwurfsprinzip, das uns hilft dieses Ziel zu erreichen:

„Streben Sie für Objekte, die interagieren, nach Entwürfen mit lockerer Bindung.“

Die bekannteste Implementierung des Observer-Musters sind die Event Handler. Die Event Handler zeichnen sich durch eine einheitliche Schnittstelle aus, durch die der Entwurf flexibel bleibt. Um jedoch ein besseres Verständnis des Observer-Musters zu erhalten, wollen wir uns an einem Beispiel anschauen, wie man das Observer-Muster selbst implementieren kann.

Weiterlesen

Das Strategy-Muster

Definition

Das Strategy-Muster (Strategie) ist eines der GoFEntwurfsmuster (Design Pattern) und gehört zu der Kategorie der Verhaltensmuster (Behavioral Pattern). Das Muster „definiert eine Familie von Algorithmen, kapselt sie einzeln und macht sie austauschbar. [Es] ermöglicht, den Algorithmus unabhängig von den Clients die ihn einsetzen, variieren zu lassen“ (EvKbF S. 24).

Beschreibung

Die einzig wahre Konstante, auf die man sich bei der Software-Entwicklung immer verlassen kann, ist die Veränderung. Das Ziel sollte daher sein, die Entwürfe stets so zu gestallten, dass Änderungen minimale Auswirkungen auf den bestehenden Code haben. Das Strategy-Muster vereinigt drei OO-Entwurfsprinzipien, die helfen dieses Ziel zu erreichen.

Weiterlesen

Besser Programmieren mit OO-Prinzipien und Entwurfsmustern

I will not write any more bad code

Der Entwicklungsprozess einer Software lässt sich sehr gut mit einem Hausbau vergleichen. In der Anfangsphase sitzt man über den Zeichnungen und Bauplänen, nachdem alle Genehmigungen eingeholt wurden, wird das Haus Stein für Stein hochgezogen und ausgebaut, dann letztendlich kommt es zur Schlüsselübergabe und die neuen Besitzer können einziehen. Doch nach einiger Zeit drückt das Grundwasser hoch, der Keller wird feucht, an den Wänden zeigen sich die ersten Risse. Klare Hinweise dafür, dass die Handwerker nicht mit der nötigen Sorgfalt gearbeitet haben. Auf die Besitzer kommen Ärger und weitere Kosten zu, die sie sich eigentlich gerne erspart hätten.

In der Softwareentwicklung ist es ähnlich. Es passiert nicht selten, dass nach der Fertigstellung, und zuweilen auch während der Entwicklungsphase eines Projektes, Mängel und Probleme sichtbar werden. Der bestehende Code muss vielleicht geändert werden um eine neue Funktionalität zu implementieren und führt u.U. zu un­vor­her­ge­se­hen Fehlern. Die Folge: die Produktions- und/oder Wartungskosten steigen, das Projekt verzögert sich und die Entwickler geraten in Stress. Diese Symptomatik ist wiederkehrend.

Weiterlesen