
Von Schichten zu Ringen – Hexagonale Architekturen erklärt

Warum Schichten nicht genug sind …
… und was man dagegen tun kann
Innen und außen statt oben und unten
Schichten 2.0
Sie startet im Inneren mit einem Domain Model, das frei von allen Abhängigkeiten die fachlichen Bausteine der Anwendung beschreibt. Der Domain Services Ring darum beinhaltet fachliche Logik, die sich über mehrere Elemente des Domänenmodells erstreckt. Er ist ausschließlich vom Domain Model abhängig und bildet gemeinsam mit diesem die gesamte Fachlichkeit ab. Diese wird genutzt von den Application Services, die anwendungsspezifische Logik wie z. B. Rechtesteuerung, implementieren. Schließlich liegen Infrastructure, User Interfaces und APIs und auch Tests in einer Schicht darum.
Abhängigkeiten verlaufen dabei immer von Außen nach Innen und niemals anders herum. Das betrifft neben Code-Abhängigkeiten natürlich auch Datenformate. Beispielsweise sollte eine Zeichenkette, deren Format von einem externen System definiert wird, niemals in einer Schicht weiter innen als Infrastructure interpretiert werden. Stattdessen definieren die inneren Schichten Formate – oder besser eigene Datentypen –, auf die die Zeichenkette durch den Adapter in der Infrastrukturschicht abgebildet wird.
Robert C. Martins Clean Architecture von 2012 kann als Derivat der Onion-Architektur mit abweichenden Bezeichnern betrachtet werden.
Als Vorteile dieses Architekturmuster lassen sich zusammenfassen:
- Die Fachlogik kann unabhängig von Infrastruktur kompiliert, deployed und wiederverwendet werden.
- Die Anwendungslogik kann von verschiedenen UIs, Batches, Daemons/Diensten und Tests gleichermaßen genutzt werden.
- Der Anwendungskern bleibt unabhängig von der Außenwelt.
- Der Austausch von Persistenzmechanismen je nach Deploymentszenario ist problemlos möglich.
- Fachlicher und technischer Code sind konsequent voneinander getrennt.
Microservices, Self-contained Systems und Domain-Driven Design
Auch zu Microservices und Self-contained Systems (SCS) erscheint die Onion-Architektur als natural fit. Jeder Service bzw. jedes SCS ist in Form seiner eigenen Zwiebel implementiert. Aus Sicht eines Systems sind alle anderen Systeme Teile der Außenwelt und dürfen als solche keine Abhängigkeiten der inneren Systemschichten darstellen.
Im Domain-Driven Design (DDD) implementiert jede Zwiebel einen Bounded Context, jeweils mit eigener Ubiquitous Language. Eine Context Map beschreibt ihre Beziehungen. Je nach Beziehungstyp nötiger Übersetzungscode lässt sich, z. B. in Form eines Anticorruption Layer, als eigene Zwiebelschicht implementieren, denn die o. g. Schichten dürfen selbstverständlich bedarfsweise erweitert werden. Mit der „Entities“ (nicht zu verwechseln mit Entities im DDD) genannten firmenweiten Fachlogik beschreibt Robert C. Martin in seiner Clean Architecture die Umsetzung des DDD-Konzepts Shared Kernel. Die Application und Domain Services-Schichten beinhalten Elemente, die auch im DDD Services und Repositories genannt werden, Domain Model enthält DDD-Entities, Value Objects und Aggregate Roots.
Fazit
Der beschriebene Architekturstil, der je nach Quelle mal Hexagonal, Ports and Adapters, Onion oder Clean Architecture genannt wird, ist eine konsequente Weiterentwicklung von Schichtenarchitekturen durch Dependency Inversion. So bleibt fachlicher Code im Anwendungskern unabhängig von technischem Code in UIs, Tests, Infrastruktur etc.
Genau wie Domain-Driven Design bieten sich hexagonale Architekturen immer dann an, wenn langlebige Softwaresysteme mit aufwendiger Fachlichkeit entworfen und nachhaltig realisiert werden sollen. Für Wegwerfsoftware, Prototypen, einfache CRUD-Systeme und andere Anwendungsfälle, in denen oft Rapid Application Development zum Einsatz kommt, erscheint der erforderliche Architekturinvest jedoch nicht angemessen.