07. Aug. 2024
Moderne Softwarearchitekturen im DDD-Umfeld
Wer sich schon einmal mit Domain-Driven Design (kurz: DDD) beschäftigt hat, kennt sicherlich das berühmte blaue Buch von Eric Evans “Domain-Driven Design: Tackling Complexity in the Heart of Software”. Der Untertitel zeigt bereits, worum es geht — den Umgang mit der Komplexität in der Softwareentwicklung und wie wir diese effektiv managen können.
Um das Konzept zu verstehen, ist es wichtig, den Unterschied zwischen "komplex" und "kompliziert" zu verstehen. Im Bereich "komplex" interagieren zahlreiche Elemente miteinander, wodurch Ergebnisse kaum vorhersehbar sind, selbst bei Expertenwissen. Stattdessen haben wir emergente Praktiken zur Verfügung — Wir müssen ausprobieren, beobachten, erkennen und darauf reagieren.
Im Gegensatz dazu bezeichnet "kompliziert" Bereiche, in denen man mit Expertenwissen gegensteuern und aufgrund einer Ursache das Ergebnis vorhersagen kann. Hier kann man auf etablierte Good Practices zurückgreifen — Wir müssen erkennen, analysieren und angemessen reagieren.
Der Übergang von einem komplexen zu einem komplizierten System erfolgt typischerweise durch die Aufteilung komplexer Problemfelder in kleinere, besser verständliche Einheiten. Das bedeutet, die Komplexität zu zerlegen. Ein wesentlicher erster Schritt, der oft unterschätzt wird, ist die Trennung zwischen der fachlichen Komplexität der Domäne und der technologischen Komplexität.
Es ist interessant zu beobachten, dass ITler sehr gut mit der technologischen Komplexität umgehen können, während die Bewältigung fachlicher Komplexität oft eine größere Herausforderung darstellt.
Daher erfolgt im DDD die Unterteilung von Domänen in Subdomänen, um die Komplexität zu reduzieren und die praktische Anwendbarkeit zu verbessern. Dennoch bleibt das Konzept oft abstrakt und schwer konkret umsetzbar. Aus diesem Grund entwickeln wir Domänenmodelle, um eine klarere und greifbarere Struktur zu schaffen.
Schichtenarchitektur als Grundlage moderner Architekturen
In seinem Buch erläutert Evans außerdem nicht nur die taktischen Muster des DDD, wie beispielsweise das Repository und Value Objects, sondern zeigt auch, wie sich diese Muster in bestehenden Architekturen, wie der Schichtenarchitektur, anwenden lassen. Und das nicht ohne Grund, denn die Schichtenarchitektur gilt für die Sofwareentwickler:innen als das fundamentale Architekturmuster und wird oft als Urgestein der Softwarearchitektur betrachtet. Ihr Zweck besteht darin, Anwendungen zu strukturieren, indem diese in Gruppen von Teilaufgaben zerlegt werden, wobei jede Gruppe auf einer bestimmten Abstraktionsebene liegt. Innerhalb der Schichtenarchitektur sind die Komponenten in horizontale Schichten organisiert (siehe Abbildung). Jede dieser Schichten erfüllt eine spezifische Rolle wie Präsentationslogik, Geschäftslogik und Persistenzlogik. Eine grundlegende Regel dieses Architekturmusters ist, dass jede Schicht nur von sich selbst und den darunter liegenden Schichten abhängig sein sollte.
Trotz ihrer weitverbreiteten Verwendung hat die Schichtenarchitektur ihre Herausforderungen, insbesondere in Bezug auf große Projekte. Die Erfahrungen haben gezeigt, dass die Schichtenarchitektur zu einer unnötigen Kopplung mit negativen Folgen führt. Die herkömmliche Schichtenarchitektur basiert gemäß der Definition auf dem Datenbank-Schema. Die Web-Schicht hängt von der Domänenschicht ab, die wiederum von der Persistenzschicht und somit von der Datenbank abhängt. Die Persistenzschicht bildet die Grundlage für das gesamte System. Daher erfordert die Abhängigkeit der Domänenschicht von der Persistenzschicht bei jeder Änderung in der Persistenzschicht potenziell auch eine Änderung in der Domänenschicht.
Nun gibt es eine Möglichkeit, die traditionelle Schichtenarchitektur zu verbessern, indem man die Art und Weise, wie Abhängigkeiten funktionieren, anpasst. Dieser Ansatz wird durch das Dependency Inversion Prinzip (kurz: DIP) ermöglicht.
Tatsächlich stellt Eric Evans im Vorwort zu Vaughn Vernons Buch “Implementing Domain-Driven Design” fest, dass Alistair Cockburns Hexagonale Architektur, besser für DDD geeignet ist als die traditionelle Schichtenarchitektur:
“... hexagonal architecture, which has emerged as a better description of what we do than the layered architecture.” — Evans
Interessanterweise vermutet Vernon in seinem Buch, dass die Onion Architektur nur eine andere Bezeichnung für die Hexagonale Architektur ist, basierend auf der Definition von Alistair Cockburn. Hier stellt sich die Frage, ob es sich dabei um denselben Architekturstil handelt.
“We refer to this architecture by the name Hexagonal, even though its name seems to have changed to Ports and Adapters. Despite its changed name, the community still refers to it as Hexagonal. The Onion Architecture has also surfaced. However, it appears to many that Onion is just an (unfortunate) alternate name for Hexagonal. We can safely assume that they are the same and stick with the Cockburn definition.” — Vernon
In den vergangenen Jahren sind verschiedene Architekturstile im Kontext von DDD entstanden, um die Komplexität von Softwareprojekten zu bewältigen. Dazu gehören
- Alistair Cockburns Hexagonal Architektur
- Jeffrey Palermos Onion Architektur
- Robert C. Martins Clean Architektur
Diese drei Architekturen sind eine praktische Umsetzung der oben genannten Definition. Dies bedeutet, dass die Onion-, Clean- und Hexagonale Architektur stark auf dem DIP basieren. Die drei genannten Architekturen können auch als die Ausprägung der Schichtenarchitektur betrachtet werden, jedoch unter Anwendung des DIPs.
In den nächsten Teilen werden wir die Details jeder einzelnen Architektur genauer betrachten.