Skip to content

Modul 4: Domain-Driven Design — Die Domäne ins Zentrum

DDD: Bounded Contexts, Aggregates, Entities, Value Objects, Repositories. Wie man Business-Logik modelliert, die bleibt.

Fortschritt0/5 Lektionen
16

Domain-Driven Design — Die Domäne ins Zentrum

Lektion 16 von 5

Was ist DDD?

Domain-Driven Design (Eric Evans, 2003) dreht die Architektur um: Nicht die Datenbank bestimmt das Modell, sondern die Geschäftsdomäne. Die Entwickler sprechen mit Domänenexperten in einer gemeinsamen Sprache (Ubiquitous Language) und modellieren die Business-Logik als ersten Burger.

Lesson 1: Ubiquitous Language

Code und Geschäft sprechen dieselbe Sprache. Heißt es im Geschäft "Versicherungsschein", heißt die Klasse Policy, nicht InsuranceRecord. Ein "Schadenfall" wird Claim, nicht DamageEvent. Diese gemeinsame Sprache zieht sich von Requirements über Tests bis in die Klassennamen.

Lesson 2: Bounded Contexts

Ein großes System hat mehrere Domänen mit unterschiedlichen Begriffen. Ein "Kunde" im Vertrieb ist nicht derselbe "Kunde" im Versand. Bounded Contexts grenzen eine Domäneneinheit ab: Jeder Context hat sein eigenes Modell, seine eigene Datenbank, seine eigene Sprache. Kontexte kommunizieren über explizite Schnittstellen (Anti-Corruption Layer).

Lesson 3: Entities und Value Objects

Entities haben Identität (eine ID) und Lebenszyklus. Zwei Customer mit derselben Adresse sind trotzdem verschieden. Value Objects haben keine Identität — sie sind durch ihre Werte definiert. Zwei Geldbeträge von 50 EUR sind identisch. Value Objects sind immutable und einfach zu testen. Faustregel: Was kein Lebenszyklus braucht, ist ein Value Object.

// Value Object: immutable, durch Werte definiert (Java Record)
record Money(BigDecimal amount, Currency currency) {
    Money add(Money other) {
        if (!currency.equals(other.currency()))
            throw new IllegalArgumentException("Währungen müssen übereinstimmen");
        return new Money(amount.add(other.amount()), currency);
    }
}

// Entity: Identität + Lebenszyklus
class Claim {
    private final ClaimId id;        // Identität — nicht der Inhalt
    private Money amount;            // Value Object innen drin
    void updateAmount(Money m) { this.amount = m; } // Zustand ändert sich, ID bleibt
}

Lesson 4: Aggregates und Aggregate Roots

Ein Aggregate ist eine Konsistenzgrenze: eine Gruppe von Entities und Value Objects, die zusammen geändert werden. Die Aggregate Root ist der einzige Einstiegspunkt — außen kann niemand ein LineItem direkt ändern, nur über die Order. Das Aggregate wahrt Invarianten (z. B. "Bestellmenge > 0").

Lesson 5: Repositories und Domänen-Services

Repositories kapseln Persistenz: save(), findById(), findByCustomer(). Die Domäne definiert das Interface, die Infrastruktur implementiert (JPA, Mongo). Domänen-Services enthalten Business-Logik, die nicht zu einer einzelnen Entity gehort (z. B. Preisberechnung über mehrere Policen).

Aggregate = Konsistenzgrenze, nicht nur eine Gruppe von Entities

Das Aggregate definiert, was zusammen geändert werden darf. Die Root wahrt die Invarianten. Ein Versto gegen die Invarianten innerhalb eines Aggregates ist ein Bug. Ein Versto zwischen Aggregaten ist eventuelle Konsistenz — und das ist in Ordnung.

Praxis-Szenario: Versicherung: Policy als Aggregate Root

Eine Policy hat mehrere Claims. Soll man Claim direkt über ein ClaimRepository ändern oder nur über Policy?

✅ Wichtige Erkenntnisse

Haken setzen, um deinen Lernfortschritt zu markieren:

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