- Fabrikmethode
-
Der Begriff Fabrikmethode (englisch Factory Method) bezeichnet ein Entwurfsmuster aus dem Bereich der Softwareentwicklung. Das Muster beschreibt, wie ein Objekt durch Aufruf einer Methode anstatt durch direkten Aufruf eines Konstruktors erzeugt wird. Es gehört somit zur Kategorie der Erzeugungsmuster.
Der Begriff Fabrikmethode kann jedoch insofern missverständlich sein, als er je nach Sprecher zwei leicht unterschiedliche Entwurfsmuster bezeichnet.
Inhaltsverzeichnis
Begriffsbedeutung gemäß Viererbande
Das Muster ist eines der sogenannten GoF-Entwurfsmuster (Gang of Four, siehe Viererbande). Es bezeichnet ein Muster, bei dem die Schnittstelle zur Erstellung eines Objektes eine (abstrakte) Methode einer Oberklasse ist. Die konkrete Implementierung der Erzeugung neuer Objekte findet jedoch nicht in der Oberklasse statt, sondern in von ihr abgeleiteten Unterklassen, die die besagte abstrakte Methode implementieren.
Das Muster beschreibt somit die Erzeugung von Produktobjekten, deren konkreter Typ von Unterklassen einer Erzeugerklasse bestimmt wird und der ein Untertyp einer abstrakten Produktklasse ist. Es wird manchmal auch als virtueller Konstruktor (virtual constructor) bezeichnet.
Abgrenzung
Der Begriff „Fabrikmethode“ wird in der Praxis auch oft einfach nur für eine statische Methode verwendet, die ein neues Objekt erzeugt, vergleichbar einem Konstruktor.
Beispiel: Statt
SomeObject o = new SomeObject();
wird unter Verwendung der umgangssprachlich als „Fabrikmethode“ bezeichneten statischen Methode geschrieben:
SomeObject o = SomeObjectFactory.createNewInstance();
In diesem Fall ist keine Verwendung von Unterklassen bzw. Polymorphismus vorgesehen.
Diese Verwendung des Begriffes Fabrikmethode ist jedoch nicht korrekt im Sinne der Gang of Four.
Verwendung
Die Fabrikmethode (in der GoF-Bedeutung) findet Anwendung, wenn eine Klasse die von ihr zu erzeugenden Objekte nicht kennen kann bzw. soll, oder wenn Unterklassen bestimmen sollen, welche Objekte erzeugt werden. Typische Anwendungsfälle sind Frameworks und Klassenbibliotheken. Bei GRASP stellt die Fabrikmethode eine Lösung dar, um sich den Zielen der geringen Kopplung und der hohen Kohäsion anzunähern.
UML-Diagramm
Das folgende Klassendiagramm zeigt die vier am Entwurfsmuster beteiligten Rollen. Konkreter Erzeuger erbt die Fabrikmethode von Erzeuger und implementiert sie so, dass sie KonkretesProdukt erzeugt, das wiederum Produkt implementiert.
Akteure
Das Produkt ist der Basistyp (Klasse oder Schnittstelle) für das zu erzeugende Produkt. Der Erzeuger deklariert die Fabrikmethode, um ein solches Produkt zu erzeugen und kann eine Default-Implementierung beinhalten. Mitunter wird für die Fabrikmethode eine Implementierung vorgegeben, die ein „Standard-Produkt“ erzeugt.
KonkretesProdukt implementiert die Produkt-Schnittstelle. (Es ist also ein konkreter Subtyp von Produkt). KonkreterErzeuger überschreibt die Fabrikmethode, um die ihm entsprechenden konkreten Produkte zu erzeugen (z. B. indem er den Konstruktor einer konkreten Produkt-Klasse aufruft).
Vorteile
Fabrikmethoden entkoppeln ihre Aufrufer von Implementierungen konkreter Produkt-Klassen. Das ist insbesondere wertvoll, wenn Frameworks sich während der Lebenszeit einer Applikation weiterentwickeln - so können zu einem späteren Zeitpunkt Instanzen anderer Klassen erzeugt werden, ohne dass sich die Applikation ändern muss.
Viele objektorientierte Programmiersprachen schreiben den Namen des Konstruktors vor. Demgegenüber kann eine Fabrikmethode (in der umfassenderen Bedeutung des Begriffes) einen aussagekräftigeren Namen haben und es kann mehrere Fabrikmethoden unterschiedlichen Namens und unterschiedlicher Semantik geben. Beispielsweise kann eine Methode Color.createFromRGB() ein Farbobjekt aus RGB-Werten erzeugen, eine Methode Color.createFromHSV() ein Farbobjekt aus HSV-Werten.
Nachteile
Die Verwendung dieses Erzeugungsmusters läuft auf Unterklassenbildung hinaus. Es muss eine eigene Klasse vorhanden sein, die die Klassen-Methode zur Erzeugung aufnehmen kann.
Beispiele
1) Virtuelle Methode in Interface oder Klasse (z. B. Fassade), die auch sonst für Objekte eines Typs zuständig ist. Unterklassen können dann spezifische Typen erzeugen. Typische Szenarien:
1.1. Erzeugen abhängiger Objekte. Beispiele:
- Java: java.sql.Connection.createStatement() - das erzeugte Statement verweist auf die Connection und „lebt in dieser“.
- .Net: System.Data.IDbConnection.CreateCommand() - das erzeugte IDbCommand verweist auf die Connection und „lebt in dieser“.
Oft haben die erzeugten abhängigen Objekte wieder Factory-Methoden für davon abhängige Objekte, z. B. hat IDbCommand eine Methode CreateParameter(). Daher lassen sich Klassen mit solchen Factory-Methoden nicht als „Factory-Klassen“ (mit Hauptverantwortung „Object Creation“) verstehen - im Unterschied zur abstrakten Fabrik.
1.2. Erzeugen unabhängiger Objekte über zentralisierte „indizierte Konstruktoren“: Eine Methode aus einer Familie von Factory-Methoden wird mit Hilfe eines Dictionaries über einen Key aufgerufen. Code-Snippet (mit C#-delegates statt Unterklassen - der Delegate-Typ repräsentiert den Erzeuger, jede konkrete anonyme Methode jeweils einen KonkretenErzeuger):
delegate IFoo CreateFoo(IContext creationParameter); static IDictionary<Key, CreateFoo> fooFactory = new Dictionary<Key, CreateFoo>(); // Statische Initialisierung: fooFactory[key1] = cp => new FooForKey1(cp); fooFactory[key2] = cp => new FooForKey2Or3(new Key2Child(cp)); fooFactory[key3] = cp => new FooForKey2Or3(new Key3Child(cp));
Aufruf:
IFoo newObject = fooFactory[key](someContext);
Erlaubt ein kompaktes, deskriptives Design der Objekterzeugung. Gefahr (insbesondere, wenn - z. B. in C# - im Dictionary direkt auf Funktionsaufrufe verwiesen wird), dass die Factory-Objekte mehr Verantwortung übernehmen.
2) „Static Factory Method“: Einzelne static-Methode, die ein Objekt eines Typs oder Unter-Typs zurückliefert. Kein „virtual constructor“ - Sinn der Sache: Zentraler, klassenbasierter Access Point für Objekterzeugung analog zu new. Erfordert manchmal Einführung einer einzelnen Klasse nur als „Factory Method Holder“. Beispiele:
- Java: java.util.Collections.singletonMap()
- Java: javax.xml.parsers.DocumentBuilderFactory.newInstance()
Ein Beispiel in C++
Das folgende Beispiel verdeutlicht die Verwendung des GoF-Musters in einem fiktiven Framework für eine Restaurant-Software.
Ein Restaurant (Erzeuger) liefert Mahlzeiten (Produkte). Das grundsätzliche Verfahren zum Liefern einer Mahlzeit ist immer dasselbe: Bestellung aufnehmen, Mahlzeit zubereiten, Mahlzeit servieren. Das lässt sich alles schon in der Klasse Restaurant implementieren bis auf das Zubereiten der Mahlzeit. Das Zubereiten (Erzeugen) ist abhängig von der Art des Restaurants: Eine Pizzeria (konkreter Erzeuger) erzeugt Pizzen (konkrete Produkte), eine Rostwurstbude erzeugt Rostwürste.
Die Klasse Restaurant implementiert hierzu eine Methode liefereMahlzeit(), die die Mahlzeit liefert, eingeschlossen des Bestell- und Serviervorgangs. Sie benutzt eine abstrakte Methode bereiteMahlzeitZu(), die die für das konkrete Restaurant konkrete Mahlzeit zubereitet (erzeugt). bereiteMahlzeitZu() ist die Fabrik-Methode und muss für jedes konkrete Restaurant entsprechend implementiert werden.
Es ist leicht einzusehen, wie dieses Framework für eine neue Art von Restaurant mit einem eigenen Mahlzeitangebot genutzt werden kann: Von Mahlzeit und von Restaurant muss jeweils eine neue Klasse abgeleitet werden, wobei die von Restaurant abgeleitete Klasse in ihrer Methode bereiteMahlzeitZu() die in diesem Restaurant angebotene Mahlzeit zubereiten (erzeugen) muss.
# include <iostream> // Produkt class Mahlzeit { }; // Konkretes Produkt class Pizza : public Mahlzeit { public: Pizza() { std::cout << "Pizza gebacken." << std::endl; } }; // Noch ein konkretes Produkt class Rostwurst : public Mahlzeit { public: Rostwurst(const char* beilage) { std::cout << "Rostwurst gebraten." << std::endl; if(beilage) { std::cout << "Serviert mit " << beilage << std::endl; } } }; // Erzeuger class Restaurant { protected: Mahlzeit* _mahlzeit; // Die Factory-Methode. Hier wird das konkrete Produkt erzeugt. virtual void bereiteMahlzeitZu() = 0; virtual void nimmBestellungAuf() { std::cout << "Ihre Bestellung bitte!" << std::endl; } virtual void serviereMahlzeit() { std::cout << "Hier Ihre Mahlzeit. Guten Appetit!" << std::endl; } public: // Diese Methode benutzt die Factory-Methode. void liefereMahlzeit() { nimmBestellungAuf(); bereiteMahlzeitZu(); // Aufruf der Factory-Methode serviereMahlzeit(); } }; // Konkreter Erzeuger für konkretes Produkt "Pizza" class Pizzeria : public Restaurant { public: virtual void bereiteMahlzeitZu() { _mahlzeit = new Pizza(); } }; // Konkreter Erzeuger für konkretes Produkt "Rostwurst" class Rostwurstbude : public Restaurant { public: virtual void bereiteMahlzeitZu() { _mahlzeit = new Rostwurst("Pommes und Ketchup"); } }; int main() { Pizzeria daToni; daToni.liefereMahlzeit(); Rostwurstbude brunosImbiss; brunosImbiss.liefereMahlzeit(); }
Verwandte Entwurfsmuster
Eine abstrakte Fabrik (Abstract Factory) wird im allgemeinen mittels Fabrikmethoden realisiert.
Fabrikmethoden werden typischerweise aus Schablonenmethoden (Template Method) heraus aufgerufen.
Fabrikmethoden finden sich oft in Singletons.
Weblinks
- Die Fabrikmethode in PHP (englisch)
- Fabrikmethode in C# (englisch)
- Beispiel für die Fabrikmethode in Java (deutsch)
- Fabrikmethode in Java (englisch)
- Factory Method (englisch)
- Fabrikmethode in Java und .NET (englisch)
Erzeugungsmuster: Abstrakte Fabrik | Singleton | Builder | Fabrikmethode | Prototyp
Strukturmuster: Adapter | Brücke | Decorator | Fassade | Flyweight | Kompositum | Stellvertreter
Verhaltensmuster: Observer | Visitor | Interpreter | Iterator | Kommando | Memento | Schablonenmethode | Strategie | Vermittler | Zustand | Zuständigkeitskette
(Klassenmuster sind kursiv dargestellt)
Wikimedia Foundation.
Schlagen Sie auch in anderen Wörterbüchern nach:
Factory-Pattern — Der Begriff Fabrikmethode (englisch Factory Method) bezeichnet ein Entwurfsmuster (engl. Design Pattern) aus dem Bereich der Softwareentwicklung. Das Muster beschreibt, wie ein Objekt durch Aufruf einer Methode anstatt durch direkten Aufruf eines … Deutsch Wikipedia
Factory Method — Der Begriff Fabrikmethode (englisch Factory Method) bezeichnet ein Entwurfsmuster (engl. Design Pattern) aus dem Bereich der Softwareentwicklung. Das Muster beschreibt, wie ein Objekt durch Aufruf einer Methode anstatt durch direkten Aufruf eines … Deutsch Wikipedia
Factory Pattern — Der Begriff Fabrikmethode (englisch Factory Method) bezeichnet ein Entwurfsmuster (engl. Design Pattern) aus dem Bereich der Softwareentwicklung. Das Muster beschreibt, wie ein Objekt durch Aufruf einer Methode anstatt durch direkten Aufruf eines … Deutsch Wikipedia
Virtual Constructor — Der Begriff Fabrikmethode (englisch Factory Method) bezeichnet ein Entwurfsmuster (engl. Design Pattern) aus dem Bereich der Softwareentwicklung. Das Muster beschreibt, wie ein Objekt durch Aufruf einer Methode anstatt durch direkten Aufruf eines … Deutsch Wikipedia
Abstract Factory — UML Diagramm: Abstrakte Fabrik Die Abstrakte Fabrik (engl. Abstract Factory, Kit) ist ein Entwurfsmuster aus dem Bereich der Softwareentwicklung und gehört zu der Kategorie der Erzeugungsmuster (Creational Patterns). Es definiert eine… … Deutsch Wikipedia
Abstrakte Fabrik — Die Abstrakte Fabrik (engl. Abstract Factory, Kit) ist ein Entwurfsmuster aus dem Bereich der Softwareentwicklung und gehört zu der Kategorie der Erzeugungsmuster (Creational Patterns). Es definiert eine Schnittstelle zur Erzeugung einer Familie… … Deutsch Wikipedia
Erzeugungsmuster — (engl. Creational Patterns) sind eine Teilmenge der Entwurfsmuster aus dem Bereich der Softwareentwicklung, die der Erzeugung von Objekten dienen. Erzeugungsmuster entkoppeln die Konstruktion eines Objekts von seiner Repräsentation. Die… … Deutsch Wikipedia
Adapter Design Pattern — Der Adapter (englisch Adapter, Wrapper) ist ein Entwurfsmuster aus dem Bereich der Softwareentwicklung und gehört zu der Kategorie der Strukturmuster (Structural Patterns). Das Muster dient zur Übersetzung einer Schnittstelle in eine andere.… … Deutsch Wikipedia
Autoboxing — Der Adapter (englisch Adapter, Wrapper) ist ein Entwurfsmuster aus dem Bereich der Softwareentwicklung und gehört zu der Kategorie der Strukturmuster (Structural Patterns). Das Muster dient zur Übersetzung einer Schnittstelle in eine andere.… … Deutsch Wikipedia
Befehlsmuster — Das Kommando oder der Befehl (engl. Command) ist ein Entwurfsmuster aus dem Bereich der Softwareentwicklung und gehört als eines der GoF Muster zu der Kategorie der Verhaltensmuster (Behavioral Patterns). Es dient zum Kapseln von Anfragen als… … Deutsch Wikipedia