In der Welt der komplexen Softwareanwendungen wird es immer wichtiger, nicht nur funktionierenden, sondern auch verständlichen und wartbaren Code zu schreiben. Domain-Driven Design (DDD) ist ein Architekturansatz, der genau darauf abzielt: Die Kerngeschäftslogik einer Anwendung in den Mittelpunkt der Entwicklung zu stellen. In Kombination mit Spring Boot – dem beliebten Framework für Java-Anwendungen – entsteht eine mächtige Kombination aus klarem Design und effizienter Implementierung.

In diesem Artikel zeigen wir, wie DDD-Prinzipien mit Spring und Spring Boot harmonieren und wie du sie in deinen Projekten sinnvoll umsetzen kannst.


Was ist Domain-Driven Design?

Domain-Driven Design, entwickelt von Eric Evans, ist ein Ansatz zur Softwareentwicklung, bei dem die Geschäftsdomäne („Domain“) im Zentrum steht. Ziel ist es, die Komplexität durch eine klare Modellierung der Geschäftslogik zu reduzieren und eine gemeinsame Sprache zwischen Entwicklern und Fachexperten (Ubiquitous Language) zu schaffen.

Wichtige Konzepte von DDD:

  • Bounded Context: Eine klare Grenze um einen bestimmten Teil der Domäne, innerhalb derer Begriffe und Modelle konsistent sind.
  • Entities & Value Objects: Entitäten haben eine Identität, Value Objects werden über ihre Attribute definiert.
  • Aggregates: Gruppen von Objekten, die als Einheit behandelt werden (z. B. Bestellung mit Bestellpositionen).
  • Repositories: Abstraktion zur Datenzugriffsschicht – unabhängig von der konkreten Implementierung.
  • Domain Events: Ereignisse, die innerhalb der Domäne auftreten und andere Teile der Anwendung informieren können.

Warum Spring und DDD passen perfekt zusammen

Spring Boot ist nicht nur ein Framework zur schnellen Erstellung von REST-APIs – es bietet durch seine modulare Architektur und Dependency Injection ideale Voraussetzungen, um DDD-Prinzipien sauber umzusetzen.

1. Klare Trennung durch Layering

Spring fördert die Aufteilung in Schichten – typischerweise:

  • Controller (Präsentationsschicht)
  • Service (Anwendungsschicht)
  • Repository (Datenzugriffsschicht)
  • Domain-Modelle (Domänenschicht)

Diese Struktur lässt sich ideal mit DDD-Layern kombinieren:

  • Domain Layer: Entities, Value Objects, Aggregates, Domain Events
  • Application Layer: Use Cases, Commands, Services
  • Infrastructure Layer: JPA, Spring Data, Messaging
  • Presentation Layer: REST-Controller

💡 Tipp: Verwende separate Packages wie com.deinprojekt.domain, com.deinprojekt.application, com.deinprojekt.infrastructure, um die Trennung klar zu machen.

2. Spring Data JPA & Repositories

Spring Data JPA vereinfacht die Implementierung von DDD-Repositories enorm. Du definierst ein Interface, das von JpaRepository erbt, und Spring generiert die Implementierung automatisch.

public interface BestellungRepository extends JpaRepository<Bestellung, UUID> {
    List<Bestellung> findByKundeId(UUID kundeId);
}

Damit bleibt dein Domain-Code sauber, und die technische Persistenz wird in die Infrastruktur delegiert.

3. Domain Events mit Application Events

Spring bietet eine eingebaute Event-Mechanismus über ApplicationEventPublisher. Ideal, um DDD-Domain-Events zu implementieren:

@Component
public class BestellungService {

    @Autowired
    private ApplicationEventPublisher eventPublisher;

    public void bestellungAbschliessen(Bestellung bestellung) {
        bestellung.abschliessen();
        eventPublisher.publishEvent(new BestellungAbgeschlossenEvent(bestellung.getId()));
    }
}

Ein Listener kann dann reagieren – z. B. eine E-Mail versenden oder eine Bestellung in einem anderen Bounded Context aktualisieren.

4. Bounded Contexte mit Spring Boot Modules

In größeren Anwendungen kannst du verschiedene Bounded Contexte als separate Spring Boot Module oder Microservices organisieren. Jedes Modul hat seine eigene Datenbank, Domain-Logik und Schnittstellen – perfekt für eine saubere Trennung.


Praxis-Tipp: So startest du mit DDD + Spring

  1. Beginne mit der Ubiquitous Language
    Arbeite eng mit Fachexperten zusammen und dokumentiere gemeinsame Begriffe.
  2. Identifiziere Aggregate und Entities
    Was hat eine Identität? Was gehört zusammen? Was ist der Aggregate Root?
  3. Nutze Spring Profiles und Packages
    Strukturiere dein Projekt klar: domain, application, infrastructure, adapter.
  4. Vermeide Anemic Domain Models
    Deine Entities sollten nicht nur Datencontainer sein – sie sollen auch Verhalten kapseln.
  5. Teste die Domain intensiv
    Domain-Logik sollte unabhängig von Spring oder Datenbanken getestet werden (Plain Unit Tests).

Fazit

Domain-Driven Design ist kein Hype – es ist ein nachhaltiger Ansatz, um komplexe Softwareprojekte beherrschbar zu machen. Spring Boot unterstützt diesen Weg durch klare Struktur, Dependency Injection und mächtige Infrastruktur-Abstraktionen.

Wenn du DDD-Prinzipien konsequent anwendest – insbesondere Bounded Contexte, Aggregates und Domain Events – und sie mit Spring intelligent verknüpfst, erhältst du eine Anwendung, die nicht nur funktioniert, sondern auch über Jahre hinweg wartbar, erweiterbar und verständlich bleibt.

🔄 Weiterdenken: Kombiniere DDD mit CQRS und Event Sourcing für noch mehr Skalierbarkeit – besonders in Microservices-Architekturen.


Hat dir dieser Artikel gefallen?
Teile ihn gern oder hinterlasse einen Kommentar! Was sind deine Erfahrungen mit DDD in Java-Projekten? Nutzt du Spring Boot bereits im DDD-Kontext?

Von harjeet