Die Factory Method und die Builder Method sind beide kreative Entwurfsmuster (Creational Design Patterns), die sich mit der Erzeugung von Objekten befassen. Während sie ähnliche Ziele haben (nämlich die Kapselung der Objekterstellung), unterscheiden sie sich in ihrer Anwendung und ihrem Fokus. Ich werde die Unterschiede zwischen den beiden Mustern und ihre jeweiligen Anwendungsfälle näher erklären.
1. Factory Method
Die Factory Method ist ein Muster, das verwendet wird, um die Instanziierung von Objekten zu delegieren. Es ermöglicht es, ein Objekt zu erstellen, ohne sich um die genaue Klasse kümmern zu müssen, die erstellt wird. Stattdessen delegiert der Client die Objekterstellung an eine spezielle Factory-Methode, die die Instanziierung und die Entscheidung über den genauen Objekttyp übernimmt.
Merkmale der Factory Method:
- Zweck: Erzeugt Objekte, aber delegiert die Verantwortung der konkreten Klassenerstellung an Unterklassen oder spezialisierte Fabriken.
- Flexibilität: Die Methode, die das Objekt erzeugt, ist in einer abstrakten Klasse definiert, und konkrete Fabriken implementieren diese Methode, um spezifische Objekte zu erstellen.
- Einzelne Instanziierung: In der Regel wird nur ein einzelnes Objekt erzeugt, und die Objekterstellung ist relativ einfach.
- Verwendung: Wird oft verwendet, wenn eine Klasse eine Familie von Objekten erzeugen muss, deren genaue Typen zur Laufzeit entschieden werden.
Beispiel der Factory Method:
from abc import ABC, abstractmethod
class Product(ABC):
@abstractmethod
def operation(self):
pass
class ConcreteProductA(Product):
def operation(self):
return "Produkt A Operation"
class ConcreteProductB(Product):
def operation(self):
return "Produkt B Operation"
class Creator(ABC):
@abstractmethod
def factory_method(self) -> Product:
pass
class ConcreteCreatorA(Creator):
def factory_method(self) -> Product:
return ConcreteProductA()
class ConcreteCreatorB(Creator):
def factory_method(self) -> Product:
return ConcreteProductB()
# Client Code
def client_code(creator: Creator):
product = creator.factory_method()
print(product.operation())
# Beispielnutzung
creator_a = ConcreteCreatorA()
client_code(creator_a) # Ausgabe: Produkt A Operation
creator_b = ConcreteCreatorB()
client_code(creator_b) # Ausgabe: Produkt B Operation
2. Builder Method
Das Builder Method-Muster wird verwendet, um komplexe Objekte schrittweise zu erstellen, indem es den Konstruktionsprozess in mehrere Schritte unterteilt. Es wird häufig verwendet, wenn das zu erstellende Objekt viele Variationen oder Konfigurationen haben kann, und der Erstellungsprozess mehrere Schritte oder Optionen erfordert.
Merkmale des Builder Patterns:
- Zweck: Baut komplexe Objekte, indem es den Erstellungsprozess in einzelne, unabhängige Schritte unterteilt, die dann von einem „Builder“ ausgeführt werden.
- Flexibilität: Der Builder ermöglicht es, Objekte schrittweise zu erstellen und gleichzeitig die Komplexität der Objekterstellung zu kapseln.
- Mehrere Objekte: Es kann zur Erzeugung von Objekten verwendet werden, die eine Vielzahl von möglichen Kombinationen und Zuständen haben (z. B. ein komplexes Dokument oder ein Gebäude).
- Verwendung: Wird häufig eingesetzt, wenn das zu erstellende Objekt eine große Anzahl an Parametern oder Eigenschaften hat und der Erstellungsprozess flexibel sein soll.
Beispiel der Builder Method:
class Product:
def __init__(self):
self.parts = []
def add_part(self, part):
self.parts.append(part)
def show_parts(self):
return ", ".join(self.parts)
class Builder(ABC):
@abstractmethod
def build_part1(self):
pass
@abstractmethod
def build_part2(self):
pass
@abstractmethod
def get_result(self):
pass
class ConcreteBuilder(Builder):
def __init__(self):
self.product = Product()
def build_part1(self):
self.product.add_part("Teil 1")
def build_part2(self):
self.product.add_part("Teil 2")
def get_result(self):
return self.product
# Client Code
def client_code(builder: Builder):
builder.build_part1()
builder.build_part2()
product = builder.get_result()
print(f"Produktteile: {product.show_parts()}")
# Beispielnutzung
builder = ConcreteBuilder()
client_code(builder) # Ausgabe: Produktteile: Teil 1, Teil 2
Unterschiede zwischen Factory Method und Builder Pattern:
Kriterium | Factory Method | Builder Method |
---|---|---|
Zweck | Objekte erzeugen, wobei die genaue Klasse zur Laufzeit entschieden wird. | Komplexe Objekte schrittweise erstellen. |
Komplexität des Objekts | Meistens ein einfaches Objekt. | Häufig komplexe Objekte mit vielen Variationen. |
Anwendungsfall | Wenn man eine Familie verwandter Objekte mit einer gemeinsamen Schnittstelle erzeugen möchte. | Wenn ein Objekt aus vielen Teilen oder Variationen besteht und der Bauprozess komplex ist. |
Typ der Objekterstellung | Erzeugt in der Regel nur ein Objekt. | Erzeugt ein vollständiges, zusammengesetztes Objekt. |
Abstraktionsebene | Abstraktion auf der Produkterstellungsebene. | Abstraktion auf der Konstruktionsprozess-Ebene. |
Verwendung von Parameter | Weniger flexibel hinsichtlich der Parametrisierung des Objekts. | Sehr flexibel in der Parameterisierung und den Bausteinen des Objekts. |
Beispiel | Erstellung eines PDFDocuments oder WordDocuments . | Aufbau eines komplexen Objekts, wie eines „Bauwerks“ oder eines „Komplexen Dokuments“. |
Wann sollte man welches Muster verwenden?
- Factory Method Pattern:
- Verwenden, wenn die Objekterstellung von einer übergeordneten Klasse oder Factory delegiert werden soll.
- Gut für die Erzeugung von Objekten, deren genaue Klasse sich zur Laufzeit ändern kann, aber die gleiche Schnittstelle haben.
- Nützlich, wenn eine Familie von Objekten erstellt werden muss, z. B. verschiedene Arten von Produkten.
- Builder Method Pattern:
- Verwenden, wenn das zu erstellende Objekt viele Varianten hat oder sehr komplex ist.
- Besonders nützlich, wenn der Erstellungsprozess viele optionale Teile umfasst und die Reihenfolge der Schritte wichtig ist.
- Ideal, wenn du ein komplexes Objekt mit vielen verschiedenen Kombinationen von Parametern erstellen musst.
Fazit:
Das Factory Method Pattern fokussiert sich auf die Abstraktion der Objekterstellung, sodass der Client nicht die genaue Klasse kennen muss, aber in der Regel ein einzelnes, einfaches Objekt erzeugt wird. Das Builder Pattern hingegen ist für die schrittweise Erstellung komplexer Objekte gedacht, wobei jeder Schritt des Bauprozesses spezifiziert werden kann.