- 1 Section
- 10 Lessons
- unbegrenzt
Factory und Abstract Factory
Stell dir vor, du betreibst eine Pizzeria. Wenn ein Kunde eine „Margherita" bestellt, gehst du nicht jedes Mal zum Lager und holst Teig, Tomatensauce, Mozzarella – sondern du sagst der Küche „Margherita!" und bekommst die fertige Pizza zurück. Du musst nicht wissen, in welchem Schrank die Tomatensauce steht. Das ist genau, was das Factory-Pattern in der Softwareentwicklung macht: es kapselt die Erzeugung von Objekten, sodass der aufrufende Code nur sagt „gib mir Typ X" – und sich nicht um die Details kümmern muss. Diese Lektion zeigt die zwei Varianten: die einfache Factory Method und die mächtigere Abstract Factory, die ganze Produktfamilien erzeugt.
1) Das Problem: new überall
Wenn du im Code an 30 Stellen new KreditkartenZahlung() stehen hast und jetzt soll ein neuer Anbieter eingebaut werden, musst du alle 30 Stellen ändern – oder schlimmer, du übersiehst eine. Außerdem ist dein Code von der konkreten Klasse KreditkartenZahlung abhängig. Sobald sich der Konstruktor ändert (neuer Parameter), musst du wieder alle 30 Stellen anpassen. Das verletzt das Dependency-Inversion-Prinzip: konkrete Klassen sollen nicht direkt verwendet werden, sondern über Interfaces.
Die Factory löst das, indem sie das new an genau einer Stelle versammelt. Wenn sich etwas ändert, fasst du nur die Factory an – der gesamte restliche Code bleibt stabil.
2) Factory Method in Aktion
Klick eine Bestellung in der Simulation – die Factory liefert dir das fertige Produkt zurück. Du gibst nur den Typ an (Margherita, Salami, ...), kennst aber die internen Klassen gar nicht. Schau dir auch den Code daneben an:
3) Drei Varianten der Factory
In der Praxis und in Prüfungsaufgaben begegnen dir drei Varianten der Factory. Sie heißen ähnlich, sind aber verschieden:
| Variante | Idee | Beispiel |
|---|---|---|
| Simple Factory | Eine Klasse mit statischer Methode, die je nach Parameter konkrete Objekte zurückgibt. Streng genommen kein GoF-Pattern, aber sehr verbreitet. | PizzaFactory.erzeuge("margherita") |
| Factory Method (GoF) | Abstrakte Klasse / Interface mit einer Methode, die Unterklassen implementieren – jede liefert ihren konkreten Typ. | Logistik-System: abstrakte Logistik mit Methode erzeugeTransport(); SchiffLogistik liefert Schiff, LkwLogistik liefert Lkw |
| Abstract Factory (GoF) | Factory für eine Familie zusammengehöriger Objekte (mehrere Typen gleichzeitig) | UI-Toolkit: WindowsFactory erzeugt Windows-Button + Windows-Checkbox + Windows-Slider; MacFactory erzeugt Mac-Versionen davon |
4) Abstract Factory – ganze Produktfamilien
Die Abstract Factory ist die mächtigere Variante. Sie wird gebraucht, wenn man eine Gruppe zusammengehöriger Objekte erzeugen will – und sicherstellen muss, dass sie zueinander passen. Klassisches Beispiel: ein UI-Toolkit, das je nach Betriebssystem ein „Windows-Set" oder ein „Mac-Set" an Bedienelementen liefern soll. Du willst nicht versehentlich einen Mac-Button neben einer Windows-Checkbox – das sieht zerschossen aus.
LinuxFactory + LinuxButton + LinuxCheckbox hinzu – ohne bestehenden Code zu ändern. Klassisches Open-Closed-Principle in Aktion. Mehr zur Struktur in UML-Klassendiagramme.5) Bekannte Verwendungen in der Praxis
Das Factory-Pattern ist eines der am häufigsten verwendeten Muster überhaupt. In der Java-Standardbibliothek findest du es überall:
Calendar.getInstance()– liefert je nach Locale eine konkrete Calendar-Klasse (Gregorianisch, Buddhistisch, ...)NumberFormat.getInstance()– Format-Objekt passend zur SpracheDriverManager.getConnection(url)– liefert je nach URL eine MySQL-, Postgres- oder Oracle-ConnectionBorderFactory.createBevelBorder(...)– Swing-Borders- In Spring:
BeanFactory/ApplicationContextsind im Kern Factories - In Python:
open()ist eine Factory – liefert je nach Modus File-Objekte mit unterschiedlichen Methoden
Auch beim REST-API-Design ist Factory verbreitet: Request-DTOs werden über Factories aus JSON gebaut, weil je nach API-Version unterschiedliche interne Strukturen entstehen müssen.
6) Wann KEINE Factory einsetzen
Wie alle Patterns kann Factory überdosiert werden. Wenn dein Konstruktor 2 Parameter hat und immer nur eine Klasse instanziiert wird, brauchst du keine Factory – das ist Over-Engineering. Faustregeln:
- Mindestens 2 Varianten: wenn es nur eine konkrete Klasse gibt, lohnt sich keine Factory.
- Erzeugungslogik ist nicht trivial: Konstruktor mit 7 Parametern, mehrere Setter, Validierungen – dann lohnt sich Factory.
- Tests werden einfacher: Factory kann gemockt werden, einfache
new-Aufrufe nicht. - Erweiterung absehbar: ist es realistisch, dass weitere Typen dazukommen?
Eine Alternative für komplexe Konstruktion mit vielen optionalen Parametern ist das Builder-Pattern – ein „Cousin" der Factory. Beispiel: Pizza.builder().teig(DICK).kaese(MOZZARELLA).sauce(TOMATE).build(). Builder wird häufig verwendet, wo eine Factory den Konstruktor mit zu vielen Parametern überladen müsste.
Zusammenfassung
Das Factory-Pattern (Erzeugungsmuster) kapselt die Erzeugung von Objekten an einer zentralen Stelle. Aufrufer kennt nur das Interface, nicht die konkrete Klasse. Drei Varianten: Simple Factory (statische Methode mit Switch), Factory Method (abstrakte Methode in Unterklassen implementiert), Abstract Factory (erzeugt ganze Produktfamilien zusammengehöriger Objekte). Vorteil: neue Typen erfordern keine Änderungen im aufrufenden Code – konform zum Open-Closed-Prinzip. Häufige Verwendung in Java-Standardbibliothek (Calendar.getInstance, DriverManager). Bei sehr komplexer Erzeugung mit vielen optionalen Parametern: Builder als Alternative.
Verwandte Lektionen: Singleton · Observer · Abstrakte Klassen & Interfaces · und mehrWeitere relevante LektionenWarum Entwurfsmuster?SOLID-PrinzipienPolymorphismusVererbungUML-KlassendiagrammKapselungDependency Injection
