Was gehört zu Softwarearchitektur?
Sicher kennen Sie die typischen Grundrisspläne von Gebäuden oder ihrer eigenen Wohnung. Da finden Sie Mauern, Türen, Fenster schematisch dargestellt (Abb. 1). Niemand in der Baubranche käme auf die Idee, ein Gebäude ohne derartige Pläne zu beginnen.
Abb. 1: Typischer Grundriss eines Gebäudes [1]
In der Informatik zeigen solche Bilder dann Komponenten („Kästchen“) und deren gegenseitige Abhängigkeiten („Pfeile“). Damit können wir die statische Struktur von IT-Systemen zeigen, also den Aufbau des Quellcodes im Großen. Solche strukturellen Pläne („Grundrisse“) stellen allerdings nur einen Teil der Architektur dar – denn darin fehlen noch die „Baumaterialien“.
Stay tuned
Regelmäßig News zur Konferenz und der Java-Community erhalten
Für Software gehört dazu die Auswahl von Programmiersprachen, Frameworks, Middleware sowie der geeigneten technischen Infrastruktur für Test und Betrieb von Systemen. Das nennen wir querschnittliche Konzepte und Technologieentscheidungen. Für unser Gebäude aus Abbildung 1 müssten wir entsprechend festlegen, ob wir mit Holz, Beton oder Ziegelstein bauen, wie wir
Wasser-, Strom- und Netzwerkleitungen verlegen und so weiter.
Fassen wir zusammen: Architektur (ob Gebäude oder IT-Systeme) definiert einerseits die Struktur („Kästchen und Pfeile“) von Systemen, andererseits grundlegende, querschnittliche Themen wie Implementierungs- und Infrastrukturtechnologien. Unter [2] führe ich die Analogie zwischen Gebäude- und Softwarearchitektur etwas weiter aus. Ein kleines Beispiel finden Sie im Kasten „Strukturen und Konzepte“. Für den Überblick an dieser Stelle soll uns das genügen.
Jetzt stellt sich die Frage, wie wir zu diesen Entscheidungen kommen beziehungsweise welche Aufgaben noch rund um diese strukturellen und querschnittlichen Entscheidungen zu erledigen sind.
Strukturen und Konzepte
Am Beispiel eines fiktiven Onlineshops möchte ich die Bedeutung und Unterschiede von Strukturen („Bausteine des Systems“) und Konzepten („Lösungsansätze, Technologien“) erläutern. Wir strukturieren unseren fiktiven (und unvollständigen) Onlineshop etwa nach Domain-Driven Design oder anderen Strukturansätzen und erhalten dabei die Bausteine, Module (oder in DDD-Sprechweise, Bounded Contexts) aus Abbildung 2.
Abb. 2: Bausteine des Onlineshops
Diese Struktur enthält allerdings noch keinerlei Informationen über die gewählte Implementierungs- oder Deploymenttechnologie oder die verwendeten Frameworks. Genau das wären unsere Konzepte – ein paar Beispiele (ebenfalls fiktiv) in der folgenden Aufzählung:
- Java/Kotlin mit Spring Boot als Backend-Technologie
- Verwendung von Angular für grafische Frontends
- Einige Bausteine werden als Self-Contained Systems (aka Microservices) eigenständig deployt und betrieben
- Apache Kafka als Messaging-System zur (zeitlichen) Entkopplung der Self-Contained Systems
- Verwendung von Jasper-Reports für sämtliche Reporting-Aufgaben
- Verwendung von PostgreSQL als Datenspeicher
- Caching lokal benötigter Daten über SQLite
Sie sehen, diese Lösungskonzepte beziehen sich teilweise (z. B. Jasper-Reports, PostgreSQL, Spring Boot) auf mehrere der Bausteine, daher rührt die Bezeichnung „querschnittliche Konzepte“. Solche Konzepte können Sie in der Architektur oftmals (fast) unabhängig von der Struktur Ihrer Bausteine oder Komponenten festlegen.
Wie geht Softwarearchitektur?
Bevor wir in der Architektur mit diesen Entscheidungen loslegen, sollten wir die grundlegenden Anforderungen an das System verstanden haben: Was soll das System leisten, welche Aufgaben oder Prozesse soll es unterstützen (aka funktionale Anforderungen)? Dazu kommt das schwierige Thema der Qualitätsanforderungen, wie Performanz, Durchsatz, Sicherheit, Änderbarkeit und so weiter (mehr dazu in [3]). Schließlich müssen Sie auch die Rand- oder Rahmenbedingungen kennen (constraints), die die Entscheidungsmöglichkeiten von Architekt:innen einschränken.
Es geht hier nicht um alle Anforderungen – denn dann wären wir ja bei einem Waterfallish-upfront-Ansatz – sondern um die aktuell bekannten und relevanten Themen einer Iteration. Primär sollten Sie sich um architekturrelevante Anforderungen kümmern. Etwa solche, die von besonders wichtigen Stakeholdern stammen (z. B. oberes Management, Auftraggeber etc.), besonders kritisch bzw. riskant sind, besonders kritische Qualitätseigenschaften betreffen oder einen ausgeprägt innovativen Charakter besitzen.
Sollten diese Anforderungen zu schwammig, unklar und widersprüchlich sein oder gar komplett fehlen, müssen Sie in der Architektur handeln statt zu jammern, also gemeinsam mit Stakeholdern nachbessern oder zumindest über die für Requirements verantwortlichen Personen nachfordern. Daher sehen Sie in Abbildung 3 auch verschiedene solcher Stakeholder symbolisch mit der Aufgabe „Anforderungen klären“ verbunden.
Abb. 3: Aufgaben in der Softwarearchitektur
Den Kern der Architekturaufgaben bildet das Duo „entwerfen“ – das sehen Sie in Abbildung 4 nochmals hervorgehoben:
- Durch „Strukturen entwerfen“ legt die Architektur die Zerlegung (auch: Schnitt) Ihres Systems fest. Sie bestimmt dabei die Bestandteile (Komponenten, Module, Services, Pakete oder wie auch immer in Ihrer gewählten Technologie die einzelnen Bestandteile eines Gesamtsystems heißen). Ganz wesentlich hierbei sind die Schnittstellen zwischen den einzelnen Bestandteilen sowie zur Umwelt.
- Durch „Konzepte entwerfen“ legt die Architektur beispielsweise die genutzten Technologien und Frameworks fest. Sie bestimmt die Art und Weise, wie die Technologien eingesetzt werden, und gibt Patterns (Muster) und Regeln für architekturrelevante Themen vor.
Stay tuned
Regelmäßig News zur Konferenz und der Java-Community erhalten
Sie finden in Abbildung 4 einen überschneidenden Bereich, den ich anhand einiger Beispiele erklären möchte: Manche Entscheidungen betreffen sowohl Strukturen als auch querschnittliche Konzepte, beispielsweise:
- Die (querschnittliche) Entscheidung, sämtliche externen REST-Schnittstellen durch einen Penetration-Test auf Sicherheitsrisiken zu prüfen. Externe Schnittstellen gehören zu den Bausteinen, den Strukturelementen des Systems, Penetration-Tests stellen ein methodisches (querschnittliches) Konzept dar.
- Die (querschnittliche) Entscheidung, gemäß Domain-Driven Design zu arbeiten und dabei jeden fachlichen Baustein (bounded context) gemäß dem Clean-Architecture-Muster zu implementieren.
- Die (querschnittliche) Entscheidung, Apache Kafka als Produkt für Messaging zu verwenden, hat Konsequenzen für alle betroffenen Bausteine (Strukturelemente).
Abb. 4: Entwurfsaufgaben: Strukturen und Konzepte
Wir arbeiten in der Architektur mit den sogenannten Stakeholdern zusammen. Neben dem Entwicklungsteam gehören dazu Fachbereiche, Auftraggebende, eventuell Behörden und Normungsgremien, Test- und QS-Abteilungen, Management, Product Owner, Nachbarprojekte und so weiter. Deswegen zählt kommunizieren zu den wesentlichen Aufgaben – mündlich wie auch schriftlich (dann nennen wir es dokumentieren). Im gleichnamigen Textkasten erkläre ich, was arc42 mit dieser Aufgabe zu tun hat.
arc42
Sie hören in Ihrer Firma immer wieder von arc42 [4], können es aber nicht einordnen? Hier eine kurze Fassung: arc42 ist ein Open-Source-Rahmenwerk zur Kommunikation (sprich: Erklärung und/oder Dokumentation) von Software- und IT-Architekturen. Sie können damit alle für Architektur und Entwicklung relevanten Aspekte Ihres Systems in einer einheitlichen Form beschreiben. Vergleichen Sie arc42 mit einem Schrank, bei dem jedes Fach bestimmte Dinge („Informationen“) über die Architektur enthält. Die Tabelle gibt eine kurze Übersicht der wesentlichen Elemente von arc42, und wie sie mit den anderen Themen dieses Artikels zusammenhängen. In [6] finden Sie viele Beispiele für die einzelnen Sektionen aus konkreten Systemen.
Sektion | Name | Bedeutung |
---|---|---|
1 | Aufgabenstellung | Eine Kurzfassung der wesentlichen Aufgaben („funktionale Anforderungen“) des Systems, der wichtigsten drei bis fünf Qualitätsanforderungen sowie eine Übersicht der beteiligten Stakeholder |
2 | Randbedingungen | Welche technischen oder organisatorischen Einschränkungen gibt es? |
3 | Kontextabgrenzung | Übersicht der externen Schnittstellen. Einbettung des Systems in dessen (fachliches + technisches) Umfeld |
4 | Lösungsstrategie | Wesentliche Elemente oder Entscheidungen der Lösung, etwa: zentrale Technologien |
5 | Bausteinsicht | Statische Struktur des Systems, Subsysteme, Komponenten, Module oder (Micro-)Services. Zeigt den Aufbau des Quellcodes aus einer Vogelperspektive. Wichtig: zeigt auch (interne) Schnittstellen |
6 | Laufzeitsicht | Wie bearbeiten die Bausteine (siehe Teil 5) wesentliche Abläufe im System? |
7 | Verteilungssicht | Technische Infrastruktur (Hardware, Netzwerke) und wie die Software darauf verteilt ist (Deployment) |
8 | Querschnittliche Konzepte | Welche Technologien werden wie eingesetzt? Beispiele: Wie speichert das System Daten, wie findet User-Interaktion statt, wie wird das System getestet, welche wesentlichen Patterns finden Anwendung? |
9 | Architekturentscheidungen | Alles, was an Entscheidungen sonst nirgendwo Platz findet. Viele Teams bringen hier ihre ADRs unter |
10 | Qualitätsanforderungen | Die Qualitätsanforderungen, die es nicht in die „Hitparade“ in Teil 1 geschafft haben |
11 | Risiken und offene Punkte | Technische Schulden, bekannte Probleme oder Risiken |
12 | Glossar | Erklärt die wichtigsten Fachbegriffe, die speziell und wichtig für dieses System sind. Bitte nicht REST oder HTTP erklären, das steht schon bei Wikipedia |
Jetzt bleibt noch die Aufgabe „Umsetzung begleiten“: Es besteht beim Arbeiten im Team immer das Risiko, dass Menschen sich missverstehen. Das ist ein menschliches Grundproblem, daher können Sie das nicht grundlegend ändern. Wenn Sie dem Team etwas erklären, könnten manche Personen diese Worte und Bilder anders interpretieren, als Sie das gemeint haben.
Solche Missverständnisse haben wir alle in der Realität schon erlebt. Sie sollten in Ihrer Architekturarbeit aktiv etwas gegen diese Missverständnisse unternehmen: Begleiten Sie die Umsetzung! Prüfen Sie beispielsweise, ob der implementierte Code so beschaffen ist, wie Sie das in der Architektur vorgesehen haben. Code-Reviews, Pull/Merge Requests oder statische Codeanalyse sind nur einige der methodischen Mittel, die Sie hierfür einsetzen können. Design-Reviews, Pair oder Mob Programming, Coding Styleguides, Referenzimplementierungen, Checklisten und noch viele andere.
Auf eine solche konstruktive Weise die Umsetzung zu begleiten, hat allerdings noch einen weiteren positiven Effekt: Ihre Teamkolleg:innen werden an manchen Stellen schlichtweg auf bessere Ideen kommen als die ursprünglichen Architekturentscheidungen. Solche strukturellen oder technischen Verbesserungen, Vereinfachungen, geschickteren Ansätze oder Ähnliches bezeichne ich als „Goldstücke, und die sollten Einzug in die Architektur halten. Insbesondere weil Sie in Ihrer Rolle als Architekt:in eben nicht alles wissen (können). Dazu kommen wir gleich, wenn wir klären, welche Person(en) überhaupt diese Architekturaufgaben erledigen können.
So viel zu den sechs Kernaufgaben der Softwarearchitektur.
Wer macht Softwarearchitektur?
Welche Optionen gibt es denn? Einerseits könnten wir monarchisch diktieren, also die Entscheidungsgewalt (im wahrsten Sinne des Wortes) auf eine einzelne Person maximal zentralisieren. Andererseits könnten wir die Architekturaufgaben einfach an das gesamte Entwicklungsteam delegieren – und komplett dezentralisieren. Dazwischen gibt es eine Vielzahl möglicher Varianten, von denen Sie in Abbildung 5 einige Vertreter finden (nach [5] und [6])
Zur Vereinfachung beziehen sich die hier skizzierten Situationen auf Teams überschaubarer Größe, circa acht bis zwölf Personen. Für größere Teams oder Gruppen aus mehreren Teams müssen zusätzliche oder andere Regeln gelten, auf die wir in dieser Übersicht nicht eingehen.
Abb. 5: Rolle und Personen: zentrale bis dezentrale Architekturarbeit
In [7] erkläre ich Vor- und Nachteile dieser fünf Modelle, daher hier nur in Kurzform: Alle diese Arbeitsweisen haben sinnvolle Anwendungsbereiche. In Off- oder Nearshore-Situationen kann eine zentralisiert-monarchische Organisation sinnvoll sein, auch wenn sie für viele Entwicklungsteams eher nach Anti-Pattern aussieht. Eine einzelne Person trifft sicher konsistente Entscheidungen, ihr mangelt es aber möglicherweise an „Schwarmintelligenz“ und ehrlichem Feedback. Andererseits kann eine rein demokratische (dezentrale) Teamarchitektur zu beliebig viel Chaos führen, obwohl sie auf den ersten Blick für viele Teams attraktiv erscheint.
Wie so oft in der IT gilt hier die „Kommt drauf an“-Regel: Jedes Team muss situativ die passende Arbeitsweise finden und für sich selbst die Frage beantworten: „Wie sollten wir Architekturentscheidungen treffen?“. Meine Vermutung (aus einigen Jahren Erfahrung): Das Modell der Agenten (also zwei bis drei Personen teilen sich die Architekturaufgaben) skaliert gut, liefert inhaltlich oftmals hervorragende Ergebnisse und trifft diese Entscheidungen recht schnell, d. h. eignet sich auch für zeitkritische Projekte.
Weder SOLID noch Clean Code sind Architektur
Die Einhaltung von Programmierregeln (wie Clean Code oder die SOLID-Prinzipien) allein machen keine solide Architekturarbeit aus. Sie können mit Clean Code unglaublich inperformanten Code schreiben oder gravierende Sicherheitslücken produzieren. Verständlich geschriebener Code gehört zu den wünschenswerten Eigenschaften von IT-Systemen, aber wenn höchste Performance gefragt ist, stehen Aspekte der Lesbarkeit und Verständlichkeit hinten an! Diese Regeln lassen die Gesamtstruktur von IT-Systemen komplett außer Acht. Sie sagen nichts über Deployment, technische Infrastruktur oder die systematische Anwendung übergreifender Konzepte. Insofern besitzen sie für Architektur wenig (!) Bedeutung, und ihre Anwendung stellt keineswegs gute oder solide Architekturarbeit sicher!
Nehmen Sie sich etwas Zeit und genießen Sie Golo Rodens ausführliche Ausführungen zu diesen Themen [8].
Fazit
Jedes System besitzt interne Strukturen („Bausteine und deren Abhängigkeiten“) und verwendet bestimmte Technologien auf eine jeweils bestimmte Art und Weise („Querschnittliche Konzepte“). Die Entscheidungen über diese beiden Themen (Strukturen und Konzepte) können Teams gezielt treffen (sprich: die Architektur aktiv gestalten) oder dem Zufall überlassen (was langfristig viele Probleme verursachen wird).
Mit aktiver Gestaltung steigt die Wahrscheinlichkeit, die notwendigen Anforderungen und insbesondere Qualitäten zu erreichen. Insofern haben Sie keine wirkliche Wahl – Architekturarbeit muss sein!
Ob Sie diese Gestaltungsarbeit einer einzelnen Person überlassen, sie auf mehrere Schultern verteilen oder im Team abstimmen, sollten Sie situativ entscheiden. In jedem Fall wünsche ich Ihnen für Ihre Architekturarbeit viel Erfolg.
Stay tuned
Regelmäßig News zur Konferenz und der Java-Community erhalten
Links & Literatur
[1] Amsterdam City Archive, Grundriss, Foto von unsplash: https://unsplash.com/de/fotos/wD9uk9fNcQU
[2]: Starke, Gernot: „Grundlagen der Softwarearchitektur – Teil 1“. INNOQ-Blog: https://www.innoq.com/de/articles/2023/07/architektur-teil-1/
[3] Q42 – das arc42 Qualitätsmodell: https://quality.arc42.org. Definiert Qualitätseigenschaften und zeigt viele konkrete Beispiele, wie entsprechende Anforderungen formuliert werden können („Qualitätsszenarien“).
[4] arc42: https://arc42.org. Dokumentation mit vielen Beispielen unter https://docs.arc42.org. Kompaktfassung als „one pager“ unter https://canvas.arc42.org
[5] Toth, Stefan: „Vorgehensmuster für Softwarearchitektur“, Carl Hanser Verlag, 2019
[6] Hohpe, Gregor: „Organizing Architecture“: https://architectelevator.com/architecture/organizing-architecture/
[7] Starke, Gernot: „Grundlagen der Softwarearchitektur, Teil 4: Wer macht das?“: https://www.innoq.com/de/articles/2023/10/grundlagen-der-softwarearchitektur-teil-4
[8] Roden, Golo: „Architektur ist überbewertet“: https://www.youtube.com/watch?v=C7TMa_kYANA und als Artikel unter https://www.heise.de/blog/Architektur-ist-ueberbewertet-und-was-wir-daraus-lernen-koennen-10191624.html