Was ist Factory vs. Builder Method?

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:

KriteriumFactory MethodBuilder Method
ZweckObjekte erzeugen, wobei die genaue Klasse zur Laufzeit entschieden wird.Komplexe Objekte schrittweise erstellen.
Komplexität des ObjektsMeistens ein einfaches Objekt.Häufig komplexe Objekte mit vielen Variationen.
AnwendungsfallWenn 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 ObjekterstellungErzeugt in der Regel nur ein Objekt.Erzeugt ein vollständiges, zusammengesetztes Objekt.
AbstraktionsebeneAbstraktion auf der Produkterstellungsebene.Abstraktion auf der Konstruktionsprozess-Ebene.
Verwendung von ParameterWeniger flexibel hinsichtlich der Parametrisierung des Objekts.Sehr flexibel in der Parameterisierung und den Bausteinen des Objekts.
BeispielErstellung 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.

com

Newsletter Anmeldung

Bleiben Sie informiert! Wir informieren Sie über alle neuen Beiträge (max. 1 Mail pro Woche – versprochen)