In diesem Blogbeitrag erläutere ich, wie man Architekturentscheidungen aus nicht-funktionalen Anforderungen strukturiert erheben, ableiten und dokumentieren kann.
Was sind nicht-funktionale Anforderungen?
Nicht-funktionale Anforderungen sind im Vergleich zu den funktionalen Anforderungen oft schwieriger aus den Steakholdern herauszubekommen und beziehen sich nicht auf die Funktion einer Software, sondern auf Qualitätsmerkmale, die in der ISO 25010 niedergeschrieben sind. Hinter dieser ISO-Norm verbirgt sich nichts anderes als der sogenannte Qualitätsbaum (siehe Abbildung 1).
Hier sind einige Beispiele für nicht-funktionale Anforderungen:
- Das System braucht maximal 2 Sekunden für eine Benutzerinteraktion
- Das System darf maximal 8 Std. im Jahr nicht zu erreichen sein
- Die Benutzeroberfläche ist leicht zu verstehen / erlernen
Nicht-funktionale Anforderungen werden in unserem Umfeld normalerweise von dem Product Owner angegeben. Allerdings müssen wir manchmal durch gezieltes Nachfragen die nicht-funktionalen Anforderungen selbst herausfinden, um die richtigen Architekturentscheidungen treffen zu können.
Der Qualitätsbaum nach ISO 25010
Die Abbildung 1 zeigt einen Ausschnitt des Qualitätsbaums nach ISO 25010, in dem die acht Qualitätsmerkmalen aufgelistet sind. Für jedes dieser acht Merkmale gibt es eine Liste von Teilmerkmalen, die eine detaillierte Betrachtung des Merkmals erlauben.
Teilmerkale von „Benutzbarkeit“ sind beispielsweise „Erlernbarkeit“, „Bedienbarkeit“ und „Fehlertoleranz gegenüber Anwenderfehler“. Für das Merkmal „Sicherheit“ stehen nicht nur „Integrität“ und „Vertraulichkeit“ auf der Liste der Teilmerkmale, sondern z.B. auch „Nachweisbarkeit“.
Der Qualitätsbaum zeigt genau, welche Kriterien eine Software überhaupt erfüllen kann und gibt dadurch jedem Architekten oder Entwickler die Möglichkeit zu hinterfragen, ob die wesentlichen bzw. wichtigsten Merkmale der Software betrachtet wurden.
Qualitätsszenarien. Was ist das und wie benutze ich sie?
Um die wichtigsten nicht-funktionalen Anforderungen methodisch weiter zu betrachten, können Qualitätsszenarien erarbeitet werden.
In der Abbildung 2 sieht man die abstrakte Beschreibung eines Qualitätsszenarios.
Ein Ereignis wirkt auf ein System ein, das mit Hilfe einer gegebenen Metrik gemessen wird. Folglich ist ein Qualitätsszenario konkret und leicht zu verifizieren. Zusätzlich wird für das System der aktuelle Zustand bzw. seine Umgebung angegeben. Beispielsweise ist das System unter Last oder es befindet sich im Internet / Intranet. Für jeden Zustand oder jede Umgebung kann es andere Szenarien geben.
Es bietet sich an zu jedem Qualitätsszenario eine oder mehrere Lösungsmöglichkeiten aufzuschreiben. Dadurch kommt man in die Ebene der Umsetzungsstrategie. Hat man eine solche Strategie, kann man noch einen Schritt weiter gehen und eine konkrete Taktik aufschreiben.
Qualitätsszenarien werden in drei Kategorien unterteilt:
Benutzungsszenarien
Ein „Benutzungsszenario” beschreibt eine nicht-funktionale Anforderungen, die sich auf die konkrete Benutzung des Systems bezieht. Zum Beispiel:
Das System braucht unter Normallast maximal 2 Sekunden, um einen Excel-Export erfolgreich durchzuführen.
Dabei ist das Ereignis der Excel-Export und die Metrik die Anzahl der Sekunden. Dieses Szenario nimmt Bezug auf das Merkmal „Performance” des Qualitätsbaums. Hier könnten Umsetzungsstrategien sein, dass nur notwendige Datenbankzugriffe gemacht werden oder auf eine performante Excel Bibliothek gesetzt wird. Weiterhin wäre eine konkrete Taktik auf ein ORM-Framework zu verzichten und die Anfragen direkt per SQL zu schicken.
Änderungsszenarien
Weiterhin gibt es „Änderungsszenarien”, die Änderungen am System beschreiben. Zum Beispiel:
Wenn ein neues Land in dem System eingepflegt wird, dann soll das in maximal vier Personentagen möglich sein. Weiterhin sollen nur Konfigurationsänderungen gemacht werden.
Dieses Szenario beschreibt das Merkmal „Änderbarkeit” des Qualitätsbaums. Eine Lösung hierfür ist beispielsweise, dass die Länder in einer oder mehreren Konfigurationsdateien gespeichert werden. Dort kann eine beliebige Anzahl an Ländern konfiguriert werden.
Ausfallszenarien
Als letzte Kategorie gibt es noch die „Ausfallszenarien”. Diese beschreiben das Systemverhalten bei einem Ausfall der Infrastruktur.
Wenn ein Server ausfällt, dann darf das System maximal zwei Minuten nicht erreichbar sein.
Hier wird auf das Merkmal „Zuverlässigkeit” eingegangen. Damit diese Anforderungen erfüllt werden kann, müssen mehrere Instanzen der Software parallel gestartet sein. Das kann z.B. erreicht werden, wenn die Server des Systems ein Cluster bilden.
Mit Hilfe der Qualitätsszenarien wird eindeutig aufgezeigt, welche Anforderungen an ein System gestellt werden. Damit diese auch in der Software oder Infrastruktur berücksichtigt werden können, sollten für jedes Szenario auch eine oder mehrere mögliche Lösungen verfasst werden.
Wie dokumentiere ich Architekturentscheidungen?
Architekturentscheidungen können in einem Architecture Decision Record (ADR) niedergeschrieben werden. Für einen ADR gibt es viele verschiedene Strukturvorschläge, die sich etabliert haben. Einige Beispiele dafür sind hier zu finden.
In einem ADR wird kurz und knapp eine Architecture Decision (AD) festgehalten. Dadurch lassen sich ADRs relativ leicht und schnell verfassen und können von jedem im Team gelesen und verstanden werden.
In einem ADR können z.B. folgenden Bestandteile benutzt werden: ein kurzer Titel, der Status (vorgeschlagen, abgelehnt, angenommen, etc.), die Problemstellung, die/der Entscheider/in, ein Datum, die möglichen Optionen inklusive Vor- und Nachteile jeder Option, sowie das Ergebnis.
Konkretes Beispiel
Anhand des folgenden Beispiels können wir mit Hilfe des Qualitätsbaums eine Architekturentscheidung treffen und diese als ADR festhalten.
Ist Zustand:
Es gibt zwei Systeme A und B, welche mit einem Messaging System miteinander verbunden sind. System A schickt Nachrichten an System B und bekommt nach Verarbeitung – erfolgreich oder Fehler – eine Antwort-Nachricht zurück. In dem Message Broker sind zwei Queues eingerichtet. Eine für das Schicken der Nachrichten von System A und eine für das Empfangen der Antwort-Nachrichten von System B.
Anforderungen:
Ein neues System C soll Informationen an System A übertragen. Diese Informationen können zu einem Land und einem Standort (Office) zugeordnet werden. Das System C soll diese Informationen mit Hilfe von Nachrichten an System A schicken. Die Nachrichten von System C sollen den normalen Betriebsablauf (Kommunikation zwischen System A und B) nicht verlangsamen oder blockieren. Falls eine Nachricht aus System C zu einem Fehler führt, soll das ebenfalls nicht den normalen Betrieb stören. Das System muss mit einer hohen Anzahl an Nachrichten zurechtkommen und im Fehlerfall soll dieser schnell identifiziert werden können.
Zuerst müssen wir uns für jede Anforderung ein Szenario überlegen und wie wir darauf reagieren wollen.
Szenarien und Lösungsvorschläge:
Das erste Szenario bezieht sich auf die Anforderung, dass die Nachrichten von System C den regulären Betriebsablauf, also die Kommunikation zwischen System A und B, nicht spürbar verlangsamen oder sogar blockieren soll. Da „verlangsamt“ nicht messbar ist, müssen wir uns für eine messbare Einheit entscheiden und diese mit dem Kunden absprechen. Folgendermaßen könnte ein Szenario formuliert sein:
Zustand des Systems ist der Normalbetrieb. In diesem Zustand beträgt der Mittelwert für die Verarbeitung der Nachrichten zwischen System A und B eine Sekunde. Schickt das System C Nachrichten an System A, dann darf die Kommunikation zwischen System A und B weder blockiert noch um 2 Sekunden verlangsamt werden.
Der Lösungsvorschlag für dieses Szenario ist beispielsweise eine separate Queue für System C anzulegen, damit die Nachrichten von System B und C getrennt voneinander übertragen und verarbeitet werden können.
Die Anforderung, dass das System eine hohe Anzahl an Nachrichten bewältigen muss, ist sehr schwammig formuliert. Was ist eine „hohe Anzahl“ an Nachrichten? Hunderte, tausende oder sogar hunderttausende? Wenn wir so eine Anforderung bekommen, müssen wir genauer nachfragen, um eine bessere Entscheidung treffen zu können. Hier nehmen wir an, dass das System C um die 50.000 Nachrichten pro Tag verschickt. Weitere Benutzungsszenarien könnten folgende sein:
Das System muss in der Lage sein 50.000 Nachrichten pro Tag zu verarbeiten. Im Fall eines Fehlers kann dieser in unter einem PT analysiert und gelöst werden.
Der Lösungsvorschlag für beide Anforderungen könnte sein, dass pro Land oder pro Standort eine eigene Queue erstellt wird. Dadurch wird erreicht, dass bei einem Fehlerfall vermutlich nur ein Land / Standort betroffen ist und die vorgeschriebene Analysezeit kann eingehalten werden, weil sich der Fehler ebenfalls nur auf ein Land / Standort beschränkt. Durch diese Lösung verteilen sich die 50.000 Nachrichten auf mehrere Queues und können so einfacher und schneller zugeordnet und analysiert werden.
Mit Hilfe dieser Szenarien können wir eine Architekturentscheidung treffen, die den Anforderungen des Systems gerecht wird. Diese Entscheidung können wir in einem ADR festhalten. Wenn dieser ADR zu einem echten System gehören würde, würde man eventuell noch genauere Infos dazu schreiben, beispielsweise das Attribut, an dem das Land erkannt werden kann.
ADR 01 – Aufteilung der Nachrichten anhand des Landes
- Status: angenommen
- Entscheider: Heinz Lethaus
- Datum: 2021-05-10
Kontext und Problemstellung
Die Anzahl der Nachrichten, die über den Message Broker geschickt werden, ist zu groß, um sie in angemessener Zeit zu verarbeiten und im Fehlerfall zu debuggen.
Mögliche Optionen
- Option 1: Aufteilung der Nachrichten anhand des Landes
- Vorteile: einfach zu Debuggen, Eingrenzung des Fehlers auf das Land
- Nachteile: erhöhter Konfigurationsaufwand
- Option 2: Aufteilung der Nachrichten anhand des Standorts
- Vorteile: einfach zu Debuggen, Eingrenzung des Fehlers auf den Standort
- Nachteile: erhöhter Konfigurationsaufwand, sehr viele Queues (unübersichtlich)
- Option 3: Verringern der Nachrichten
- Vorteile: weniger Nachrichtenbelastung
- Nachteile: erhöhter Programmieraufwand zum aggregieren der Nachrichten
Ergebnis
Gewählte Option: „Option 1“, da diese Option beim Debuggen unterstützt und mögliche Probleme auf das Land eingrenzt. Außerdem ist diese Option mit vertretbarem Aufwand umzusetzen und betreiben.
Damit diese Option umgesetzt werden kann, müssen folgende Anpassungen gemacht werden:
- Der Message Broker muss die Nachrichten anhand des Landes auf die Queues weiterleiten
- System A muss aus mehrere Queues Nachrichten empfangen können
Positive Konsequenzen
- Kürzerer Analyseaufwand
Negative Konsequenzen
- Zusätzlicher Konfigurationsaufwand