Fabrikmethode
aus Wikipedia, der freien Enzyklopädie
1) Die Fabrikmethode (englisch Factory Method) ist ein Entwurfsmuster aus dem Bereich der Softwareentwicklung und gehört zur Kategorie der Erzeugungsmuster (Creational Patterns). Das Muster zeigt wie die Erzeugung von Objekten funktioniert, wenn die Unterklassen selbst bestimmen, von welchen Klassen die zu erzeugenden Objekte sind. Es ist eines der sogenannten GoF-Muster (Gang of Four, siehe Viererbande). Dieses Muster wird manchmal auch als virtueller Konstruktor (virtual constructor) bezeichnet.
2) Der Begriff Fabrikmethode wird in der Praxis auch oft für eine statische Methode verwendet, die ein neues Objekt erzeugt. In diesem Fall ist keine Verwendung von Unterklassen bzw. Polymorphismus vorgesehen.
Inhaltsverzeichnis |
[Bearbeiten] Verwendung
Die Fabrikmethode findet Anwendung, wenn:
- eine Klasse die von ihr zu erzeugenden Objekte nicht kennen kann bzw. soll (1), 2)) oder
- Unterklassen bestimmen sollen, welche Objekte erzeugt werden (nur 1)).
Typische Anwendungsfälle sind Frameworks und Klassenbibliotheken.
[Bearbeiten] UML-Diagramm
[Bearbeiten] Akteure
- Produkt
- Basistyp (Klasse oder Schnittstelle) für das zu erzeugende Produkt
- Erzeuger
- definiert die Fabrikmethode, um ein solches Produkt zu erzeugen
- (mitunter wird für die Fabrikmethode eine Implementierung vorgegeben, die ein "Standard-Produkt" erzeugt)
- KonkretesProdukt
- implementiert die Produkt-Schnittstelle (Subtyp von Produkt)
- KonkreterErzeuger (nur bei 1))
- überschreibt die Fabrikmethode um konkrete(re) Produkte zu erzeugen
- determiniert damit das konkrete Produkt (z.B. indem er den Konstruktor einer konkreten Klasse aufruft)
[Bearbeiten] 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.
- In C++, Java und ähnlichen Sprachen kann eine Fabrikmethode im Gegensatz zu einem Konstruktor einen aussagefähigeren Namen haben, z.B. Color.CreateRGB(...) vs. Color.CreateHSB(...).
[Bearbeiten] Nachteile
- 1) Die Verwendung dieses Erzeugungsmusters läuft auf Unterklassenbildung hinaus.
- 2) Es muss eine eigene Klasse vorhanden sein, die die statische Methode aufnehmen kann (das hat schon zu Forderungen geführt, dass in Java- oder C#-Schnittstellen statische Methoden erlaubt werden sollten).
[Bearbeiten] 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.Add(key1, delegate(IContext cp) { return new FooForKey1(cp); }); fooFactory.Add(key2, delegate(IContext cp) { return new FooForKey2Or3(new Key2Child(cp)); }); fooFactory.Add(key3, delegate(IContext cp) { return 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()
[Bearbeiten] Verwendung in Analyse für GUI-basierte Programme
1) "metaphorische Verwendung": GUI-Aktionen (häufig "Neu-Buttons" einer Toolbar) "erzeugen" neue Objekte abhängig davon, welcher Dialog gerade gezeigt wird. Beispiel:
- MS-Outlook hat Button "Neu", der je nach ausgewähltem Elemente-Typ (E-Mail, Kalender, Aufgaben, ...) ein jeweils anderes Objekt erzeugt (neue E-Mail, neuer Termin etc.).
2) In der Praxis kein relevantes Analysemuster.
[Bearbeiten] Verwandte Entwurfsmuster
Eine abstrakte Fabrik (Abstract Factory) wird i. A. mittels Fabrikmethoden realisiert.
Fabrikmethoden werden typischerweise aus Schablonenmethoden (Template Method) heraus aufgerufen.
Fabrikmethoden finden sich oft in Singletons.
[Bearbeiten] 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)
Erzeugungsmuster: Fabrikmethode | Abstrakte Fabrik | Erbauer | Prototyp | Einzelstück
Strukturmuster: Adapter | Adapter | Brücke | Kompositum | Dekorierer | Fassade | Fliegengewicht | Stellvertreter
Verhaltensmuster: Interpreter | Schablonenmethode | Zuständigkeitskette | Kommando | Iterator | Vermittler | Memento | Beobachter | Zustand | Strategie | Besucher | Plugin
(Klassenmuster sind kursiv dargestellt)