Christoph Haag
Christoph ist Softwareentwickler mit einer Passion für Musik
03.03.2025 | 5 min Lesezeit
In den Softwareprojekten, die ich gesehen und bei denen ich mitentwickelt habe, begegnen mir immer wieder ähnliche Aussagen, Probleme und Herausforderungen. Hier ein paar Klassiker:
Oft ist die Ursache all dieser Dinge: mangelnde Anpassbarkeit, Nachvollziehbarkeit, Einfachheit und Verständlichkeit.
Im Zentrum der Software steht ihre Architektur. Leidet ein Software-Projekt unter den genannten Symptomen, lohnt es sich, seine Architektur unter die Lupe zu nehmen.
Software architectures are structures that support the use cases of the system. [...] Your architectures should tell readers about the system, not about the frameworks you used in your system. Robert C. Martin - Clean Coder Blog
Die Screaming Architecture stellt die Frage: "Was ist zu sehen, wenn die Struktur des Projektes betrachtet wird?".
Eine React Applikation? Eine dotnet Core Web Api mit Entity Framework und Migrations? Abstraktionen und Patterns, wie z.B. Repositories, Adapters, Clients, DomainServices, Models, DTOs, etc.? Eine Applikation, die EventSourcing, oder CQRS verwendet?
Screaming Architecture fordert, dass Architektur Use-Cases sichtbar macht.
src/
-- common/
-- components/
-- contexts/
-- hooks/
-- pages
-- Api/
-- Db/
-- Domain/
-- Events/
-- Services
src/
-- features/
-- projects/
-- time-tracking/
-- users
Allein durch diese einfache Strukturänderung werden viele Dinge klarer.
Die Vertical Slice Architecture (VSA) führt den Gedanken der Screaming Architecture weiter. Sie fordert (in ihrer Reinform), dass ein Use-Case in sich abgeschlossen ist und alle notwendigen Bestandteile enthält, um den Use-Case umzusetzen.
Das Prinzip dahinter:
Minimize coupling between slices, and maximize coupling in a slice. Jimmy Bogard - Vertical Slice Architecture
Die Stärke dieses Ansatzes ist, dass eine Änderung innerhalb eines Use-Cases zu keinen Nebeneffekten in anderen Use-Cases führt. Die Komplexität des Gesamtsystems wird in kleinere, überschaubare Teile aufgeteilt. Dadurch führen auch neue Anforderungen nicht wesentlich zu einer steigenden Komplexität des Gesamtsystems. Das Gesamtsystem muss nicht verstanden werden, um einen Teilaspekt nachvollziehen zu können.
Innerhalb eines Slices können verschiedene Unter-Architekturen und auch Technologien verwendet werden. Es ist damit nicht gesagt, dass das erstrebenswert oder immer eine gute Idee ist. Aber es ist eine Freiheit, die es in klassischen Schichten-Architekturen häufig nicht gibt. Ein einfacher Use-Case kann einfach umgesetzt werden. Es müssen nicht die gleichen Patterns, Abstraktionen, etc. verwenden werden, wie bisher im Projekt.
VSA und Microservices sind nicht dasselbe; schließen sich aber gegenseitig nicht aus. Microservices verfolgen das Ziel, einzelne Features unabhängig deploybar zu machen.
Ein häufiges Gegenargument ist, dass VSA zu dupliziertem Code führt. Und das ist oft korrekt. Darin liegt jedoch in meinen Augen die größte Stärke dieses Ansatzes: Ein Sichtwechsel.
Entwickler denken häufig, es sei ihre Aufgabe, Abstraktionen zu schaffen. Dinge zu vereinheitlichen. Den selben Code für verschiedene Dinge wiederzuverwenden. Problematisch wird dieser Ansatz, wenn er zur Notwendigkeit, oder gar zur Kultur wird.
Duplication is far cheaper than the wrong abstraction. Sandi Metz - The wrong abstraction
Die richtige Abstraktion zu finden ist schwierig. Nicht nur in einem frühen Stadium des Projekts und nicht nur als Neuling. Zum Zeitpunkt der Implementierung der Abstraktion wird implizit eine Annahme über die Zukunft getroffen - dass diese auch für zukünftige Anforderungen treffend ist.
We don't know what the future of code will be. Kent C. Dodds - AHA Programming 💡
Durch Duplikation wird der Druck genommen, die richtige Abstraktion zu finden.
Ein weiteres Gegenargument ist, dass verschiedene Patterns für dasselbe Problem verwendet werden. Im Wesentlichen ist dies dem duplizierten Code sehr ähnlich, nur umgedreht. Der Code ist ein anderer, das Problem ist identisch.
Probleme und ihre Lösungen sehen häufig auf den ersten Blick gleich aus, sind aber im Detail doch unterschiedlich. Entwickler sollten statt mit dem 'Abstraktionsauge' und dem DRY-Prinzip im Hinterkopf zuerst den Use-Case verstehen und eine passende Lösung finden. Wenn sich über die Zeit ein Pattern herauskristallisiert, kann es immernoch in eine Abstraktion, 'shared Code', Dokumentation, Best Practice, etc. überführt werden.
Premature Abstraction is the Root of All Evil Zack - zackoverflow
Verschiedene Patterns können auch als Chance verstanden werden. Neues ausprobieren. Sich nicht von alten Mustern einschränken lassen. Außerdem können Entwickler unabhängig voneinander an verschiedenen Lösungen arbeiten. Teams skalieren besser und Neueinsteiger können schneller produktiv werden.
Screaming Architecture und Vertical Slice Architecture sind Ansätze, die helfen, Uses-Cases in den Vordergrund zu rücken. Software-Projekte werden in kleinere und unabhängigere Teile zerlegt, wodurch die eingangs erwähnten architekturbedingten Symptome mangelnder Anpassbarkeit und Nachvollziebarkeit verbessert werden können.
Ich habe das Thema hier sicher nur angeschnitten. Die verlinkten Artikel sind alle für sich sehr lesenswert und geben einen tieferen Einblick in die Thematik.