Entscheidungskategorie Domänenkern

Der Domänenkern beschreibt den fachlichen Kern des Systems im Inneren der domänenzentrierten Architekturmodelle und besteht aus Domänenmodell, -logik sowie -regeln.

Einordnung in die domänenzentrischen Architekturmuster

ArchitekturmusterBetroffener Verantwortungsbereich
Clean ArchitectureEntities Ring
Hexagonal ArchitectureDomain Hexagon
Onion ArchitectureDomain Service Onion
Domain Onion

Architekturentscheidung #1: Nach welchem Prinzip wird das Domänenmodell implementiert?

Vorbedingung

Keine

Soft Standard

Mit der Entscheidung für DDD wird das Ziel verfolgt, ein Domänenmodell zu implementieren. Dabei ist das Aggregate, Entity und Value Object Muster zu verwenden.

Entscheidungskontext

Für die Implementierung eines Domänenmodells muss die Grundsatzentscheidung zwischen dem Rich Domain Model (1.1) und dem Anemic Domain Model (1.2) getroffen werden.

Diese Entscheidung legt fest, wie das Domänenmodell implementiert wird und an welchen Stellen Geschäftslogik und -regeln verortet werden.

Das Rich Domain Model besagt, dass die Fachlogik im Domänenobjekt (Aggregate, Entity, Value Object) implementiert wird. Dadurch wird eine ausdrucksstarke Benennung der Methoden ermöglicht, die auf der Fachlichkeit basiert (im vgl. zu set-Methoden). Eine spezielle Form des Verhaltens findet sich in der implementierung von Domänenobjekt-bezogenen Geschäftsregeln.

Ein Anemic Domain Model enthält nur die Eigenschaften sowie dazugehörige getter und setter. Fachlogik und Validierung werden ausschließlich in Domain Services implementiert. Das Anemic Domain Model gilt auch als Anti-Pattern, da dies oft zu einem Verlust der Fachsprache im Modell und zu unnötige Komplexität führt im vgl. dazu die Fachlichkeit im Modell abzubilden.

Der Mittelweg stellt das Moderately Rich Domain Model (1.3) dar. Hier werden Daten und Geschäftsregeln im Objekt gekapselt, weitere Fachlogik wird in Domain Services ausgelagert.

Risiko wenn diese Entscheidung nicht aktiv getroffen wird

  • Es entstehen uneinheitliche Implementierungen des Domänenmodells
  • Die Fachlichkeit wird nicht ausreichend im Modell abgebildet und unnötige technische Komplexität entsteht

Entscheidungsalternativen

EntscheidungsalternativenKurzbeschreibung
1.1 Rich Domain ModelDas Domänenobjekt enthält:
1) Daten
2) Geschäftsregeln
3) Verhalten
1.2 Moderately Rich Domain ModelDas Domänenobjekt enthält:
1) Daten
2) Geschäftsregeln
1.3 Anemic Domain ModelDas Domänenobjekt enthält ausschließlich Daten

Architekturentscheidung #2: Wie soll das Value Object Muster in der Implementierung angewendet werden?

Vorbedingung

Architecture DecisionEntscheidung
11.1 Rich Domain Model
1.2 Moderately Rich Domain Model

Annahme
Wird eine 1.3 Anemic Domain Model eingesetzt, wird die Implementierung von Value Objects als nicht wertstiftend angesehen. Die Entscheidung #2 muss in diesem Fall nicht getroffen werden.

Entscheidungskontext

Wird dem Rich oder dem Moderately Rich Domain Model gefolgt, entsteht in Teams i.d.R. die Frage, ob jeder Fachwert als Value Object implementiert werden soll, denn in einem komplexen Aggregate können potenziell viele Value Objects entstehen.

In der Literatur gibt es auf deiner eine Seite die Empfehlung einen fachlichen Wert immer als Value Object zu implementieren. Auf der anderen Seite existiert ein großen vielfalt von unterschiedlichen Implementierungsbeispiele von Value Objects. Wird diese Aussage mit den Codebeispielen in Verbindung gebracht, wird deutlich, dass die Empfehlung nicht bedeutet, dass keine primitiven Datentypen mehr verwendet werden dürfen.

Dennoch ist das, das eine extrem der Entscheidung: Jeder Fachwert wird mittels Value Object Muster implementiert. (2.1) Ein Value Object wird angewendet mit den Zielen,

  • Die Fachliche Ausdrucksstärke in der Paketstruktur und auf Klassenebene zu erhöhen
  • Eine Fachliche Typisierung durch die Eigenschaft der Selbst-Validierung zu realisieren
  • Fachliche Logik bezogen auf den Fachwert zu kapseln
  • Die Seiteneffektfreiheit durch die Eigenschaft der Immutabilität, insbesondere bei Paralellität, zu erhöhen

Es gibt jedoch auch Fälle, in denen die Implementierung eines Fachwertes als Value Object nicht notwendig ist. Dies ist dann der Fall, wenn die fachliche Typisierung und Selbst-Validierung und die Kapselung von Fachlogik nicht notwendig ist. Ein pragmatischer Ansatz, Value Objects nur zu verwenden, wenn diese Eigenschaften notwendig sind (2.2), ist valide und in Abhängigkeit der konkreten fachlichen Anforderungen zu betrachten.

Auf Value Objects zu verzichten und ausschließlich primitive Datentypen zu verwenden (2.3), ist ebenfalls eine Möglichkeit, wird jedoch in der DDD-Community als Anti-Pattern bewertet. Dies ist insbesondere bei komplexen Aggregates mit viel und/oder komplexen Geschäftsregeln und Logik der Fall, dann dies dann vollständig im Aggregate oder in einer Entity implementiert werden muss.

Risiko, wenn diese Entscheidung nicht aktiv getroffen wird

  • Es entstehen uneinheitliche Implementierungen der Fachwerte und in der Konsequenz auch die Prüfung von Geschäftsregeln
  • Es entstehen widersprüchlich Implementierungsvarianten und die Verständlichkeit des Codes wird erschwert
  • Entwickler/innen ist unklar, welche Implementierungsvariante wann für einen Fachwert zu wählen ist

Entscheidungsalternativen

EntscheidungsalternativenKurzbeschreibung
2.1 Use always value object patternJeder fachliche Wert wird als Value Object implementiert.
2.2 Conditional use of value object patternNur fachliche Werte, die Logik oder Geschäftsregeln enthalten, werden als Value Object implementiert.
2.3 No usage of value object patternJeder fachliche Wert wird als primitiver Datentyp implementiert. Logik und Geschäftsregeln werden in der (Root) Entity implementiert.

Architekturentscheidung #3: Wie wird die fachliche Konsistenz bei Verwendung des Anemic Domain Model gesichert?

Vorbedingung

Architecture DecisionEntscheidung
11.3 Anemic Domain Model

Entscheidungskontext

Wird das Anemic Domain Model angewendet, muss für die Invarianten und Verhalten ein anderes Element als die Domänenobjekte selbst gefunden werden. Eine Möglichkeit hierfür ist der Domain Service (3.1), jedoch würde dies dazu führen, dass die Verantwortung für Fachlogik und fachliche Validierung in einem Muster verortet wird. Bei erhöhter fachlicher Komplexität, empfiehlt sich daher die Einführung eines neuen Elements in der Mustersprache, wie z.B. ein Validator (3.2).

Risiko, wenn diese Entscheidung nicht aktiv getroffen wird

  • Es entstehen uneinheitliche Implementierungen der Fachwerte und in der Konsequenz auch die Prüfung von Geschäftsregeln
  • Dies reduziert die Verständlichkeit und Entwickler/innen ist unklar, welche Implementierungsvariante wann für einen Fachwert zu wählen ist

Entscheidungsalternativen

EntscheidungsalternativenKurzbeschreibung
3.1Domänenobjekt-bezogene Geschäftsregeln und Logik werden Domain Services implementiert.
3.2Domänenobjekt-bezogene Geschäftsregeln wird in Validators und Domänenobjekt-bezogene Logik in Domain Services implementiert.

Architekturentscheidung #4: Wie werden Domänenobjekt-bezogene Geschäftsregeln implementiert?

Vorbedingung

Keine

Entscheidungskontext

Unabhängig davon, in welchem Element der Mustersprache die Implementierung von Geschäftsregeln verortet wird, stellt sich die Frage wie die Implementierung erfolgen soll.

Eine Möglichkeit ist die Implementierung der Geschäftsregeln nativ mit den Mitteln der genutzten Programmiersprache (4.1).

Eine weitere Möglichkeit ist die Implementierung mit einer proprietären Abstraktion zur Wiederverwendung von Validierungsregeln (4.2). Diese Abstraktion koppelt auf lange Sicht, fachliche Komponenten des Systems und sollte daher mit Bedacht eingesetzt werden.

Eine dritte Möglichkeit ist der Einsatz einer Third-Party Library (4.3), die Out-of-the-Box Validierungsregeln enthält. Dies kann die Implementierung von Geschäftsregeln beschleunigen. Jedoch sollte die Abhängigkeit zur Library hinsichtlich Funktionsumfang, Stabilität, Erweiterbarkeit und Einfachheit bewertet werden.

Risiko, wenn diese Entscheidung nicht aktiv getroffen wird

  • Es entstehen uneinheitliche und evtl. widersprüchliche Implementierungen für die Prüfung von Geschäftsregeln
  • Dies reduziert die Verständlichkeit und den Entwickler/innen ist unklar, welche Implementierungsvariante wann für die Implementierung von Geschäftsregeln zu verwenden ist
  • Mehrere Libraries werden für denselben Zweck verwendet, was zu einer unnötigen Komplexität führt
  • Ein Mix aus nativer Implementierung und Third-Party Libraries führt zu einer schwer nachvollziehbaren Verflechtung von Regeln, die keine fachliche Konsistenz gewährleisten

Entscheidungsalternativen

EntscheidungsalternativenKurzbeschreibung
4.1 NativeNative Implementierung mit den mitteln der genutzten Programmiersprache.
4.2 Native AbstractionNative Implementierung mit einer proprietären Abstraktion zur Wiederverwendung von Validierungsregeln.
4.3 Third-Party LibraryEinsatz einer Third-Party Library die Out-of-the-Box Validierungsregeln enthält.

Architekturentscheidung #5: Welche Strategie der Objekterzeugung, wird für komplexe Fachobjekte verwendet?

Vorbedingung

Keine

Entscheidungskontext

Die Mustersprache des taktischen Designs beschreibt die Factory (5.1), die die Verantwortung für die Objekterzeugung übernimmt, wenn dies nicht mehr durch einen einfachen Konstruktor (5.4) am Objekt selbst möglich ist.

Als Ergänzung oder Alternative zur Factory kann das Builder-Pattern (5.2) eingesetzt werden. Als Ergänzung bzw. Alternative zum Konstruktor, ist Static Factory Method Pattern (5.3) zielführend.

In der Regel gibt es nicht den einen Erzeugungsprozess für Domänenobjekte. Folglich ist die Kombination der Lösungsstrategien für jeweilige passende Einsatzszenarien ein guter Weg. Wann welche Muster eingesetzt wird, sollte basierend auf einem gemeinsamen Verständnis in der Architekturentscheidung festgehalten werden.

Szenarien

Im Folgenden sind vier Szenarien aufgeführt, die Objekterzeugung in domänenzentrischen Architekturmuster bedingen.

  1. Ein User führt Anwendungsfälle aus, bei denen das Domänenobjekt erzeugt werden muss
  2. Der Zustand eines Domänenobjektes muss aus dem Speicher gelesen werden
  3. Der Zustand eines Domänenobjektes ergibt sich aus unterschiedlichen Quellen (z.B. Speicher und externer Service)
  4. Die Geschäftslogik bedingt die (Neu-)Erzeugung von Domänenobjekten als Bestandteil der Kontrollfluss der Domänenlogik

Risiko

  • Eine uneinheitliche und potenziell widersprüchliche Verwendung der Erzeugungsmuster erhöht die strukturelle Komplexität
  • Dies reduziert die Verständlichkeit und Entwickler/innen ist unklar, welches Erzeugungsmuster für einen Fachwert zu wählen ist, was zu weiteren Abweichungen und Varianten führt

Entscheidungsalternativen

EntscheidungsalternativenKurzbeschreibung
5.1 Factory
5.2 Static Factory Method
5.3 Constructor
5.4 Builder
5.5 Joker

Entscheidungskategorie Anwendungsfälle

@ToDo

Geschäftsregeln stellen im Kontext der Entscheidungskategorie Anwendungsfälle anwendungsfall-spezifische Regeln dar.

Einordnung in die domänenzentrischen Architekturmuster

ArchitekturmusterBetroffener Verantwortungsbereich
Clean ArchitectureUse Case Ring
Hexagonal ArchitectureApplication Hexagon
Onion ArchitectureApplication Onion

Architekturentscheidung #6: Wie werden Use Cases geschnitten?

Vorbedingung

Keine

Entscheidungskontext

Use Cases sind Schnittstellen der fachlichen Applikation und werden aus der Perspektive der Domäne definiert. Dabei können verschiedene Heuristiken zum Einsatz kommen, und keine Heuristik ist per se die beste.

Ziel ist es im Team zu definieren, welche Heuristik überwiegend oder in Abhängigkeit eines bestimmten Szenarios verwendet werden soll. Diese Szenarien der Anwendung sind auf Basis eines gemeinsamen Verständnisses in der Architekturentscheidung zu dokumentieren.

Risiko, wenn diese Entscheidung nicht aktiv getroffen wird

  • Es entstehen uneinheitliche Varianten der Implementierung und Benennung von Use Cases
  • Dies reduziert die Verständlichkeit und Entwickler/innen ist unklar, welche Implementierungsvariante wann für einen Use Case zu wählen ist
Entscheidungsalternativen
EntscheidungsalternativenKurzbeschreibung
6.1 By Function
6.2 By Command & Query
6.3 By (Root) Entity
6.4 By Source
6.5 By Consumer
6.6 Joker

Entscheidungskategorie Mappings

Die Entscheidungen über den Einsatz von Mapping-Strategien beeinflusst den Kopplungsgrad des Systems im Gesamtbild. Mappings können jedoch auch Overhead darstellen, weshalb eine gute Balance abgestimmt auf die Anforderungen notwendig ist.

Einordnung in die domänenzentrischen Architekturmuster

ArchitekturmusterBetroffene Verantwortungsbereich Two-Way MappingBetroffene Verantwortungsbereich Full Mapping
Clean ArchitectureInterface Adapters RingInterface Adapters Ring
Use Case Ring
Hexagonal ArchitectureAdapters HexagonAdapters Hexagon
Application Hexagon
Onion ArchitectureAdapters OnionAdapters Onion
Application Onion

Architekturentscheidung #7: Welche Mapping-Strategie wird als Default-Strategie verwendet und für welche Szenarien eignen sich alternative Strategien?

Vorbedingung

Keine

Entscheidungskontext

@ToDo

Risiko, wenn diese Entscheidung nicht aktiv getroffen wird

@ToDo

Entscheidungsalternativen

EntscheidungsalternativenKurzbeschreibung
7.1 One-Way Mapping Strategy
7.2 Two-Way Mapping Strategy
7.3 Full Mapping Strategy
7.4 No Mapping
7.5 Joker

Architekturentscheidung #8: Wie werden Mappings implementiert?

Enabling Architecture DecisionEntscheidung
77.2 Two-Way Mapping Strategy
7.3 Full Mapping Strategy

Entscheidungskontext

Für die Two-Way und die Full Mapping Strategie stellt sich die Frage, wie Mappings implementiert werden sollen. Eine einheitliche Lösungsstrategie wird empfohlen, um die Komplexität in der Implementierung nicht unnötig zu erhöhen. Jede Variante hat Vor- und Nachteile, und letztendlich muss sie auch den Vorlieben des Teams entsprechen.

Risiko, wenn diese Entscheidung nicht aktiv getroffen wird

@ToDo

Entscheidungsalternativen

EntscheidungsalternativenKurzbeschreibung
8.1 Native as adapter logic
8.2 Native with a Mapper
8.3 Third-Party Library
8.4 Joker

Entscheidungskategorie Modularisierung

Starting Architecture Decisions der Entscheidungskategorie Modularisierung haben übergreifenden Charakter und gelten in allen domänenzentrischen Architekturmuster auf gleiche Weise.

Architekturentscheidung #9: Vertikale vs horizontale Schichtung

Vorbedingung

Keine

Entscheidungskontext

@ToDo

Risiko, wenn diese Entscheidung nicht aktiv getroffen wird

@ToDo

Entscheidungsalternativen

EntscheidungsalternativenKurzbeschreibung
9.1 Vertical Layers by Aggregate-Module
9.2 Horizontal Layers by Rings / Hexagon

Architekturentscheidung #10: Wie wird Modularisierung umgesetzt?

Vorbedingung

Entscheidungskontext

@ToDo

Risiko, wenn diese Entscheidung nicht aktiv getroffen wird

@ToDo

Entscheidungsalternativen

EntscheidungsalternativenKurzbeschreibung

Architekturentscheidung #11: Wie werden fachliche Module strukturiert?

Vorbedingung

Architecture DecisionEntscheidung
99.1 Vertical Layers by Aggregate-Modules

Entscheidungskontext

Das fachliche Modul wird abgeleitet auf Basis eines Aggregate (Root Entity). Innerhalb dieses Moduls werden die Verantwortungsbereiche (Ring, Hexagon bzw. Onion) des domänenzentrischen Architekturmuster abgebildet. Hierfür gibt es verschiedene Lösungsstrategien, die die architektonischen Elemente mehr oder weniger stark zum Ausdruck bringen.

Zur Förderung der Verständlichkeit wird bei Modulen ab mittlerer Größe und Komplexität eine ausdrucksstarke Variante, d.h. 11.1 und 11.2, empfohlen.

Risiko, wenn diese Entscheidung nicht aktiv getroffen wird

@ToDo

Entscheidungsalternativen

EntscheidungsalternativenKurzbeschreibung
11.1 Architectural Expressive
11.2 Architectural Expressive Application
11.3 Rings/Hexagon as Layers
11.4 Joker

Architekturentscheidung #12: Wie wird die Abhängigkeit zwischen zwei Aggregates aufgelöst?

Vorbedingung

Keine

Entscheidungskontext

Im taktischen Domain-Driven Design wird eine Entkopplung auf Basis der Grenzen von Aggregates verfolgt. Aggregates haben einen unabhängigen Lebenszyklus.

Falls ein fachlicher Zusammenhang hergestellt werden muss, darf ein Aggregate ein anderes Aggregate nur über dessen Identität referenzieren. Die Referenz muss zur Laufzeit aufgelöst werden.

Abhängigkeiten dieser Art sind musterartig und gleichartig zu behandeln, um die Komplexität gering zu halten.

Welches Muster als Standard dienen kann und in welchen Szenarien auf alternative Lösungsstrategien zurückgegriffen wird, muss als kollaborative Architekturentscheidung im Team getroffen werden.

Risiko, wenn diese Entscheidung nicht aktiv getroffen wird

@ToDo

Entscheidungsalternativen

EntscheidungsalternativenKurzbeschreibung
12.1 Application Service Pattern
12.2 Adapter-Out Use-Case-In Pattern
12.3 Events
12.4 Joker