Skip to content

Modul 2: Design Patterns — bewährte Lösungen wiederverwenden

GoF-Muster in der Praxis: Singleton, Factory, Strategy, Observer, Decorator, Adapter, Facade. Wann welches Muster — und wann keins.

Fortschritt0/5 Lektionen
6

Design Patterns — bewährte Lösungen wiederverwenden

Lektion 6 von 5

Was sind Design Patterns?

Design Patterns sind benannte, bewährte Lösungen für wiederkehrende Design-Probleme. Sie sind kein Code zum Kopieren, sondern eine gemeinsame Sprache: „Nimm hier ein Strategy" transportiert mehr als zehn Minuten Erklärung. Die GoF-Muster (Gang of Four, 1994) gliedern sich in drei Gruppen: Erzeugungsmuster, Strukturmuster und Verhaltensmuster.

Lesson 1: Erzeugungsmuster — Singleton und Factory

Singleton garantiert genau eine Instanz (z. B. Konfiguration, Thread-Pool). Vorsicht: Singletons verstecken globale Abhängigkeiten und machen Tests schwer. Factory Method delegiert die Objekterzeugung an Unterklassen oder eine zentrale Fabrik — der Aufrufer kennt nur das Interface, nicht die konkrete Klasse. In Spring übernimmt der Container die Fabrik-Rolle (Beans).

Lesson 2: Strategy — Verhalten austauschbar machen

Strategy kapselt einen Algorithmus hinter einem Interface und macht ihn austauschbar. Statt if/else-Kaskaden für Rabattberechnungen, Sortierungen oder Validierungen: eine Strategy pro Variante. Der Aufrufer wählt zur Laufzeit — oder der Container injiziert die passende Implementierung (siehe Modul 1, DIP).

interface DiscountStrategy { BigDecimal apply(BigDecimal price); }

class VipDiscount implements DiscountStrategy {
    public BigDecimal apply(BigDecimal price) { return price.multiply(new BigDecimal("0.80")); }
}
class NoDiscount implements DiscountStrategy {
    public BigDecimal apply(BigDecimal price) { return price; }
}

// Aufrufer kennt nur das Interface — neue Rabatttypen ohne Änderung
class PriceCalculator {
    private final DiscountStrategy discount;
    PriceCalculator(DiscountStrategy discount) { this.discount = discount; }
    BigDecimal finalPrice(BigDecimal price) { return discount.apply(price); }
}

Lesson 3: Observer — Ereignisse verteilen

Observer entkoppelt Sender und Empfänger: Ein Subject benachrichtigt alle registrierten Observer, ohne sie zu kennen. Klassisch für Event-Handling, Message-Broker (Kafka, RabbitMQ) und Spring ApplicationEvents. Vorteil: Neue Empfänger registrieren sich, ohne den Sender zu ändern (OCP).

Lesson 4: Strukturmuster — Adapter, Decorator, Facade

Adapter übersetzt ein fremdes Interface in das erwartete — ideal für Legacy- oder Drittanbieter-Code. Decorator fügt einem Objekt zur Laufzeit Verhalten hinzu (Java InputStream-Wrapping). Facade bietet eine vereinfachte Schnittstelle vor einem komplexen Subsystem — ein Service-Layer vor Domänenklassen und Repositories ist eine Facade.

Lesson 5: Wann kein Muster?

Patterns sind Werkzeuge, keine Ziele. Ein Singleton für etwas, das eh nur eine Instanz hat, ein Observer für einen einzigen Listener, eine Factory für eine einzige Implementierung — das ist Komplexität ohne Nutzen (YAGNI). Faustregel: Erst das Problem benennen, dann prüfen, ob ein Muster es löst — nicht umgekehrt.

Patterns und SOLID gehören zusammen

Design Patterns sind SOLID in Klein: Strategy implementiert OCP und DIP, Observer implementiert OCP, Facade reduziert Kopplung. Wer Patterns ohne die Prinzipien anwendet, baut meist „Pattern Overengineering" — viele Klassen, keine Verbesserung. Wer die Prinzipien versteht, erkennt Patterns als konkrete Lösungen dafür.

Praxis-Szenario: Zahlungsanbieter austauschbar machen

Dein Shop integriert zuerst PayPal, später Stripe, Klarna und eine interne Wallet. Der jetzige Code hat PayPal-Logik direkt im Checkout-Service verdrahtet. Wie strukturierst du das mit Patterns?

✅ Wichtige Erkenntnisse

Haken setzen, um deinen Lernfortschritt zu markieren:

    This site uses essential cookies for Stripe payments. No tracking cookies.