Dependency Inversion - Hexagonal-, Onion- & Clean-Architecture im Vergleich, Teil 2

Von: Thomas Bayer
Datum: 8. Juli 2024

Diese Einleitung führt leicht verständlich in die Softwarearchitekturen Hexagonal-, Onion- und Clean-Architecture ein.

In diesem Teil geht es um das Dependency Inversion Prinzip, auf welchem die Hexagonal-, Onion- und Clean-Architecture basieren.

2. Dependency Inversion

In der Schicht mit der Geschäftslogik verwenden wir das KundenSQLRepository und sind damit von der Datenschicht abhängig. Da die Domain die Daten-Schicht kennt, ist es nicht möglich, die Datenschicht auszutauschen, ohne Code-Änderungen in der Fachlichkeit vorzunehmen.


Abbildung : Abhängigkeit von der Datenschicht

Um die Unabhängigkeit von der Technik zu erreichen, können wir zunächst ein Interface einführen, das vom KundenRepository implementiert wird. Der Trick dabei ist, dass wir dieses Repository nicht, wie man vielleicht vermuten würde, in der Datenschicht platzieren. Stattdessen ist das Interface Teil der Fachlichkeit und kommt daher in die Domain-Schicht. Die konkrete Implementierung des Interfaces bleibt jedoch in der Datenschicht.


Abbildung : Einführung eines Interfaces

Die Geschäftslogik ist jetzt zur Compilezeit nur vom Interface abhängig, und das befindet sich in derselben Schicht. Die Domain enthält keinen Code mehr, der von Details wie z.B. einer SQL-Datenbank abhängig ist.

Die KundenRepository-Klasse, die das Interface für SQL-Datenbanken umsetzt, bleibt in der Datenschicht und ist jetzt von der Domain abhängig. Damit dreht sich die Richtung der Abhängigkeit um. So funktioniert Dependency Inversion, eines der SOLID Prinzipien.


Abbildung : Dependency Inversion: Umkehr der Abhängigkeit

Zur Laufzeit genügt der Domain die Schnittstelle allein nicht mehr. Es wird dann eine konkrete Implementierung benötigt, damit beim Aufruf von Speichern auch tatsächlich etwas passiert. Damit die Domain das tatsächliche Repository verwenden kann, kombinieren wir Dependency Inversion mit Dependency Injection. Beim Start der Anwendung setzt ein Dependency Injection Framework, wie Spring Boot oder .NET, eine Referenz auf die passende Implementierung.


Abbildung : Dependency Inversion und Injection im Einsatz

Anstatt einer Implementierung für SQL könnte auch eine für NoSQL eingesetzt werden oder eine Mock-Implementierung für Tests.


Abbildung : Austausch der Datenbank

Was haben wir gemacht? Wir haben für einen Teil der Infrastruktur ein Interface eingeführt, das die Technik abstrahiert. Wichtig ist, dass dieses Interface Bestandteil der Domain ist. Dadurch hat sich die Richtung der Abhängigkeit gedreht, und die Fachlichkeit ist nicht mehr von der Technik abhängig.

Mit den Grundlagen zum Dependency Inversion Prinzip ist der Grundstein für das Verständnis der hexagonalen Architektur gelegt.

Video

Anstatt zu lesen kannst du auch das Video zum Artikel auf YouTube anschauen.