Wenn wir in einer agilen Weise Software entwickeln, dann akzeptieren wir, dass wir zu Beginn nicht genügend Wissen haben, um ein gutes Produkt zu entwickeln. Wir werden auf dem Weg viel dazu lernen. Nur so ist es uns möglich, das bestmögliche Produkt zu bauen.
Achtung, fertig, los! Aber mit Vision
Und jetzt sollen wir mit ganz wenig Wissen also die Softwarearchitektur definieren? Das geht nur schrittweise. Damit wir uns aber nicht verirren, sollten wir die grobe Richtung kennen. Dazu lohnt es sich, mit allen Stakeholdern einen initialen Requirements-Workshop abzuhalten. Neben den üblichen funktionalen Anforderungen geht es für den Architekten um Szenarien zur Beschreibung von nicht-funktionalen Anforderungen und Qualitätseigenschaften. Dies umreisst das System grob – sozusagen eine Architektur-Vision – und gibt einen ersten Einblick zu der erwarteten Anzahl Benutzer, Datenmengen und Skalierungsbedürfnissen. Idealerweise lassen sich auch schon Milestones in der Evolution der Softwarearchitektur erkennen. So kann es sein, dass die erste Version nur für den internen Gebrauch und mit wenig Anforderungen an Performanz konzipiert ist. Weitere Versionen sind dann für eine wesentlich grössere Benutzerbasis angedacht – mit den entsprechenden Security- und Skalierungsanforderungen.
Iterativ und inkrementell für frühes Feedback
Diese erste Architektur-Skizze verbessern wir dann schrittweise – iterativ und inkrementell. Iterativ bedeutet, dass wir ein Feature so reduziert wie möglich umsetzen. Gerade gut genug, um Feedback einzuholen. Dieses Feedback lassen wir in die nächste Iteration einfliessen. Inkrementell bedeutet, dass wir ein Feature nach dem anderen dem System hinzufügen. Oft werden noch fehlende Teile simuliert, um ein lauffähiges System zu haben, welches wir demonstrieren können.
Immer schön flexibel bleiben
Damit sich unsere Softwarearchitektur auch später im Verlauf weiterhin den neuen Erkenntnissen und geänderten Wünschen anpassen kann, muss die Architektur modularisiert sein und den Regeln von Clean Architecture folgen. Dadurch erhalten wir ein System aus Einzelteilen, die sich fast unabhängig voneinander entwickeln und austauschen lassen. Dies unterstützt auch die inkrementelle Entwicklung.
Bei der Dekomposition des Domänenproblems in möglichst unabhängige Teile sollte immer in den Businessprozessen gedacht werden, welche die Software unterstützen. Eine möglichst direkte Abbildung der Businessprozesse in die Software erleichtert spätere Anpassungen, etwa bei Businessänderungen. Die Komposition der möglich unabhängigen Teillösungen zu einem integrierten System sollte folgende Punkte berücksichtigen: Transaktionen/Kompensation über mehrere Module oder Services, Datenhoheit und -synchronisation. Nur eine starke Entkopplung der Einzelteile unterstützt die Flexibilität nachhaltig.
Schrittweise, iterative und inkrementelle Erweiterung der Architektur mit stetigem Feedback.
Entscheidungen über Entscheidungen
Eine der Hauptaufgaben eines Architekten ist es, technische Entscheidungen herbeizuführen. Im agilen Umfeld bedeutet dies aber, bei Entscheidungen zuerst zu schauen, was wirklich schon entschieden werden muss und was noch herausgezögert werden kann, um in der Zwischenzeit mehr Wissen für eine bessere Entscheidung aufzubauen.
Viele Entscheidungen können dabei in Teilentscheidungen aufgeteilt werden. So geht die Frage, wie die Daten im System persistiert werden sollen, mit einer ganzen Kette von Entscheidungen einher:
- Müssen wir Daten speichern? Um von den Stakeholdern Feedback zu holen, nein. Das geht auch mit in-memory Daten. Um das System zu releasen, ja.
- Welche Daten haben wir überhaupt? Das lässt sich besser entscheiden, wenn die Businessabläufe in einer ersten Iteration umgesetzt sind und Feedback eingeholt wurde.
- Welche Form sollen die Daten haben? Relational, dokumentbasiert, Key-Value, graphbasiert? Da wir jetzt wissen, welche Daten wir haben, ist dieser Entscheid meist einfach.
- Welche Technologie wollen wir einsetzen? Die Technologie lässt sich meist hinter einer Abstraktion «verstecken»; so kann die Technologie erst sehr spät konkret gewählt werden und die Businesslogik lässt sich davon unabhängig implementieren.
Dieses Split-and-Defer-Muster lässt sich auf die meisten Architekturaspekte anwenden.
Evolution kennt viele Pfade
Viele Entscheidungen haben mehrere valable Varianten. Oft lässt sich mit dem aktuellen Wissenstand kein eindeutig bester Weg identifizieren. Hier hilft es, die Evolutionspfade zu visualisieren. Dies bedeutet, pro Variante aufzuzeigen, welche Konsequenzen daraus resultieren und welche Entscheidungen später getroffen werden müssen und wie diese von der momentanen Entscheidung betroffen sind. Fragen Sie sich: «Wie erreichen wir unsere Architekturvision, wenn wir diesen Weg einschlagen?» Die so entstehenden Pfade helfen bei der Diskussion im Team über den einzuschlagenden Weg und die Konsequenzen und Risiken. Mehr Infos dazu finden Sie hier.
Einfachheit über Alles
Um flexibel zu bleiben, ist Einfachheit die wichtigste Eigenschaft einer Softwarearchitektur und des Programmcodes. Denn wenn der Programmcode einfach zu verstehen ist, dann sind bei Änderungen die Seiteneffekte leicht überschaubar – und Fehler können vermieden werden. Einfacher Code lässt sich somit gut erweitern oder verändern. Dies führt wiederum dazu, dass sich der Code einfach Refaktorisieren lässt, was wiederum zu noch einfacherem Code führt. Ein sich selbst verstärkender Regelkreis.
Ein Design oder eine Softwarearchitektur ist aber nicht einfach so einfach. Die erste Umsetzung ist meist unnötig kompliziert, und erst durch häufige Refaktorisierung wird aus einer rein funktionierenden Lösung eine einfache, flexible Lösung. Konsequentes Continuous-Refactoring führt immer wieder zu überraschend einfachen Lösungen – nach 3 oder 4 kleinen Refaktorisierungen erkennt man oft grössere Refaktorisierungen, die das Design radikal vereinfachen.
Link zu meiner Blog-Artikel-Serie: https://www.planetgeek.ch/2019/10/18/software-architecture-in-the-agile-world-part-1-intro/
Der Autor
Urs Enzler
Urs Enzler war als Expert Software-Architekt .NET bei bbv tätig. Als agil gesinnter Softwareentwickler spricht er an Konferenzen und Communityanlässen gerne über architektonische Herausforderungen und über das Lernen im Team. Enzler ist Co-Gründer der .NET Usergroup Zentralschweiz.
Werden Sie Agilist - mit den Booklets von bbv!
Möchten Sie sich vertieft mit agiler Softwareentwicklung auseinandersetzen? In unseren Booklets finden Sie weiterführende Informationen - von Guidelines zur Einführung von Scrum über das Requirements Engineering in agilen Projekten bis zu Erfahrungsberichten zur Zero Bug Policy.
Zu den Booklets