Nachdem in den vorangegangenen Artikeln [1] und [2] die Softwarearchitektur im Allgemeinen und der Softwarearchitekt mit seinen Aufgaben und Fähigkeiten im Mittelpunkt standen, soll in diesem Beitrag die Entwicklung von Softwarearchitekturen näher erläutert werden. Die zentrale Frage lautet: „Wie kommt der Architekt zu einer tragfähigen Architektur für ein zu entwickelndes Softwaresystem?“
Gemeinsame Vision
Zu Beginn entsteht zunächst eine gemeinsame Idee des zu entwickelnden Systems. Dabei geht es im ersten Schritt darum, den Zweck und die Hauptaufgaben zu beschreiben. Das klingt zunächst recht einfach, aber in der Regel gibt es eine Vielzahl an Beteiligten, die unterschiedliche Interessen verfolgen und die Einfluss auf die Entwicklung des Systems nehmen.
Es ist an diesem Punkt sehr wichtig, dass alle betroffenen Interessengruppen mit einbezogen werden. Die gemeinsame „Systemvision“ muss auf eine breite Akzeptanz stoßen, um als Basis für das weitere Vorgehen dienen zu können.
Diese Vision wird im Normalfall durch einen Geschäftsvorfall (business case) motiviert und in der fachlichen Sprache der entsprechenden Domäne formuliert.
Systemanforderungen
Aus dieser gemeinsamen Systemidee, muss der Architekt nun die architekturrelevanten Aspekte herausarbeiten. Das heißt, es gilt die Architekturtreiber zu identifizieren. Daher ist es notwendig, dass die Anforderungen vollständig erfasst und genau verstanden werden. In der Regel finden sich die wichtigsten architekturrelevanten Aspekte unter den fünf bis zehn am höchsten priorisierten fachlichen Anforderungen bzw. Anwendungsfällen.
Für eine solche Priorisierung bedarf es der Abstimmung mit allen Interessensvertretern, denn jeder Betroffene stellt andere Anforderungen und verfolgt unterschiedliche Ziele mit dem zu entwickelnden System. Betriebliche Aspekte wird ein Administrator sicherlich anders bewerten, als ein Vertriebsmitarbeiter, dafür sind die Kenntnisse und Fähigkeiten einfach zu verschieden. Um dies zu erleichtern, sollte das System in seinem Umfeld
näher betrachtet werden. Mit dem Systemkontext existiert dafür ein geeignetes Mittel.
Systemkontext
Der Systemkontext stellt das zu entwickelnde System aus der Vogelperspektive dar. Es zeigt die Grenzen zu anderen Systemen auf und liefert damit Hinweise auf mögliche Schnittstellen und Infrastrukturkomponenten. Außerdem zeigt es, welche Benutzer auf welche Art mit dem System interagieren (siehe Abbildung 1).
Abb. 1: Systemkontext.
Um den Systemkontext zu ermitteln, bietet sich ein Fragenkatalog oder eine Checkliste an, die folgende Aspekte analysieren sollte:
- Was sind die Hauptaufgaben des Systems?
- Wer benutzt das System (Anwendergruppen, externe Systeme, etc.)?
- Wie wird das System von den verschiedenen Anwendern benutzt (Benutzeroberfläche, Batch-Betrieb, etc.)?
- Welche Schnittstellen hat das System?
- Wie und welche Arten von Daten verarbeitet das System (DB, Files, Speicher, etc.)?
- Wie wird das System bedient / gesteuert (extern, intern, regel-/ereignisbasiert, etc.)?
Durch genaue Betrachtung des Systemkontextes lassen sich typische Anwendungsfälle ermitteln, die bezüglich Wirkung, Nutzen und Risiko bewertet werden. Diese Bewertung ist Grundlage für die oben angesprochene Priorisierung der Anforderungen. Für eine
solche Bewertung gibt es unterschiedliche Verfahren und Mittel. Später werden wir noch sehen, wie dies am Beispiel der nicht-funktionalen Anforderungen durchgeführt werden kann. Wesentlich ist aber, dass die Anforderungen mit den größten Auswirkungen (bzgl. Wirkung, Nutzen und Risiko) auch die höchste Priorisierung erfahren.
Hier sei noch einmal darauf hingewiesen, dass durch die Berücksichtigung aller Interessenvertreter bei der Erfassung der Anforderungen, natürlich auch deren unterschiedliche Ziele in die Bewertung einfließen müssen. Der Architekt ist hier als Moderator in der Pflicht, die
Anforderungen im notwendigen Umfang zu klären und ggf. zu vervollständigen.
Der Systemkontext liefert neben den Anwendungsfällen auch erste Hinweise auf die Schlüsselabstraktionen des Systems. Damit sind neben Fachklassen und funktionalen Blöcken auch Ausprägungen von Schnittstellen gemeint. Diese Informationen sind es, die später die Grundlage für einen ersten Architekturentwurf liefern.
Nicht-funktionale Anforderungen und Qualitätsszenarien
Bevor jedoch der eigentliche Entwurf der Architektur erfolgt, gilt es noch einen Blick auf die Qualitäten der nicht-funktionalen Anforderungen zu werfen. Sie sind in Kombination mit den funktionalen Anforderungen die maßgeblichen Architekturtreiber. Allerdings haben nicht-funktionale Anforderungen leider oft die Eigenschaft, nicht oder nicht ausreichend beschrieben worden zu sein.
In vielen Anforderungsbeschreibungen finden sich daher oftmals keine oder nur pauschalierte Aussagen zu Aspekten wie Performanz, Erweiterbarkeit, Bedienbarkeit, Wartbarkeit, Verfügbarkeit, Skalierbarkeit, Sicherheit oder Zuverlässigkeit. Formulierungen wie: „Eine ausreichende Verarbeitungsgeschwindigkeit wird vorausgesetzt“ oder „Das System ist so zu konstruieren, dass jederzeit eine Erweiterung von Funktionalitäten möglich ist“ sind leider keine Seltenheit.
Eine geeignete Beschreibung für die nicht-funktionalen Anforderungen findet man in den s.g. Qualitätsszenarien. Sie werden auch in der Architekturbewertungsmethode ATAM (Architecture Tradeoff Analysis Method) verwendet, die am Software Engineering Institute der Carnegie Mellon University entwickelt wurde. Danach werden die wichtigsten Anwendungsfälle (funktionale Anforderungen) auf ihre Qualitäten bzgl. der nicht-funktionalen Aspekte untersucht und in kurzen prägnanten Szenarien formuliert. Beispiele dazu könnten folgendermaßen aussehen:
- Performanz:
Das Ergebnis einer Suche nach einem Produkt über die Benutzeroberfläche muss dem Anwender nach spätestens 5 Sekunden angezeigt werden. - Verfügbarkeit:
Der Zugang über das Webinterface zum Kundenkonto muss dem Anwender 24 Stunden an 7 Tagen der Woche über das gesamte Jahr zur Verfügung stehen. - Erweiterbarkeit:
Ein neu zu erstellender Bericht muss mit einem Aufwand von max. 2 Personentagen in das System integriert werden können.
Der Nutzen der Qualitätsszenarien liegt zunächst in der Konkretisierung der geforderten Qualitäten. Die nicht-funktionalen Anforderungen werden dadurch messbar und können später u.a. als Abnahmekriterien herangezogen werden. Für die Architekturentwicklung werden sie jedoch noch mit einem weiteren Hilfsmittel kombiniert, dem Utility Tree.
Utility Tree
Zweck des Utility Tree ist die Systematisierung und Priorisierung der Qualitätsszenarien. Wie schon im ersten Artikel dieser Reihe [1] ausgeführt, lässt sich die Qualität der nicht-funktionalen Anforderungen nicht für alle Anforderungen gleichzeitig im gewünschten Maß optimieren. Bestimmte Qualitätsziele stehen im Widerspruch zueinander. So steht zum Beispiel das Ziel der Erweiterbarkeit (meist durch Hinzufügen zusätzlicher Schichten erreicht) konträr zum Ziel einer hohen Performance (zusätzliche Schichten benötigen zusätzlichen Code mit längerer Laufzeit). Durch die Priorisierung der Szenarien und deren Zuordnung zu einer Qualität lassen sich später die geeigneten Architekturmittel zum Architekturentwurf ermitteln. Der Architekt kann also entscheiden, ob er (gemäß obigen Beispiels)
Architekturmittel zur besseren Unterstützung der Erweiterbarkeit oder der Performance wählt.
Für die Priorisierung der Qualitätsszenarien werden zwei Kriterien herangezogen. Dies ist zum einen der Einfluss, den das Szenario auf den Erfolg des Gesamtsystems hat. Es spiegelt damit den Nutzen und die Wirkung wider. Und zum anderen das Risiko, das angestrebte Qualitätsziel zu verfehlen. Die Skala zur Bewertung der beiden Kriterien kann frei, nach eigenen Bedürfnissen gewählt werden. In der Praxis hat sich herausgestellt, das meistens eine Einteilung in hoch (H), mittel (M) und niedrig (L) ausreichend ist.
Die Einteilung der Qualitätsattribute und der Kategorien (2. Ebene des Baums) kann beliebig gewählt werden. Die ISO-Norm 9126 [3] beschreibt allerdings einen Rahmen, der sich zur Verwendung im Utility Tree gut eignet. Abbildung 2 zeigt hier zu Anschauungszwecken einen Baum mit allen Attributen und Kategorien. Zweige, die keine Qualitätsszenarien beinhalten, werden aber in der Praxis nicht aufgeführt, ebenfalls würde das Attribut Funktionalität (funktionale Anforderungen) weggelassen werden.
Abb. 2: Utility Tree.
Schrittweise Verfeinerung der Architektur
Mit den Anwendungsfällen, dem Systemkontext und dem Utility Tree stehen nun genügend Informationen zur Verfügung, um den eigentlichen Architekturentwurf zu beginnen. Ausgangspunkt für den ersten Entwurf ist das zu entwickelnde System als Black Box, so wie es im Zentrum des Systemkontextes steht. Anhand der o.g. Überlegungen wird das System nun in einzelne Module zerlegt und dann iterativ verfeinert (siehe Abbildung 3).
Abb. 3: Verfeinerung der Architektur.
Die Szenarien des Utility Tree geben entsprechend der Priorisierung die Richtung vor. Je höher ein Szenario priorisiert ist, umso mehr Gewicht hat die Berücksichtigung der dazugehörigen Qualitätsattribute bei der Entwicklung der Architektur. Bei jedem Schritt zur Verfeinerung sind die folgenden Aspekte zu beachten:
In unserem ersten Artikel dieser Reihe [1] wurden die Prinzipien einer guten Architektur bereits erläutert. Die Zerlegung gemäß dem Ansatz „Teile und Herrsche“ sollte diesen Prinzipien Rechnung tragen. Besonders den Aspekten der Trennung der Verantwortlichkeiten (Separation of concerns), der hohen Kohärenz und der losen Koppelung sollte erhöhte Aufmerksamkeit geschenkt werden.
Abhängigkeiten zwischen einzelnen Modulen sollten auf das notwendigste Maß begrenzt und zyklische Abhängigkeiten sollten grundsätzlich vermieden werden! Wenn es gelingt, die Strukturen so einfach wie möglich zu
halten und damit die Komplexität zu begrenzen, sind die Grundlagen für eine gute, tragfähige Architektur gelegt.
Die Frage, wie weit ein Modul zerlegt werden sollte, die Zerlegung also architekturrelevant ist, lässt sich nicht ganz so einfach beantworten. Die Antwort: „Soweit es für die Architektur notwendig ist“, bleibt zu schwammig. Das liegt an der unscharfen Trennung zwischen Architektur und Design (im Sinne des klassischen Begriffs aus z.B. OOA/OOD), deren Übergang fließend ist. Klar ist aber, dass ein Modul nicht weiter zerlegt werden sollte, sofern es nur um die Beschreibung interner,
privater Details geht, die evtl. nur für die Implementierung wichtig sind aber für das „große Ganze“ keinen Wert besitzen.
Architekturmuster und -stile
Die Kunst bei der Zerlegung der Module, besteht für den Architekten im Wesentlichen darin, die geeigneten Architekturmittel zu finden. D.h. er muss zur Umsetzung der fachlichen Funktionalitäten Softwarestrukturen beschreiben, die den nicht-funktionalen Qualitätsszenarien (Utility Tree) in geeigneter Weise entsprechen. Er versucht für die Architekturtreiber der einzelnen Qualitätsszenarien passende Strategien zu entwickeln.
Dazu wird er sich in der Regel seines Erfahrungsschatzes bedienen oder nach Referenzarchitekturen für das Problem suchen. Architekturmuster und -stile bieten hier eine hervorragende Möglichkeit, um mit verschiedenen Strategien die Erfüllung der unterschiedlichen Qualitätsszenarien zu unterstützen. Analog zu den Entwurfsmustern in der Programmierung haben sich hier wiederverwendbare, bewährte Strukturen herauskristallisiert, die Softwarearchitekten immer wieder in gleicher Form verwenden. Zu den bekanntesten zählen Schichtenarchitekturen, Pipes and Filters, Microkernel oder Blackboard. Eine detaillierte Beschreibung dieser Strukturen wird Gegenstand eines späteren Artikels sein.
Dokumentation
Ein Ziel der Dokumentation von Softwarearchitekturen ist es, die Kommunikation mit den Interessenvertretern zu ermöglichen. Für die spätere Überprüfung der Architektur wird der Architekt genau dies benötigen. Deshalb sollte er die Architektur mit den passenden Mitteln und im geeigneten Umfang dokumentieren. Wie dies systematisch erfolgen kann, wird ebenfalls in einem folgenden Artikel detaillierter erläutert. Für den Moment soll nur erwähnt werden, dass es auf jeden Fall sinnvoll ist, sich der vier folgenden Sichten zu bedienen:
- Systemkontext (Gesamtsystem als Black Box, Anwendungsfälle, Systemumgebung)
- Bausteinsicht (statischer Aufbau, Klassen, Komponenten, Pakete)
- Laufzeitsicht (dynamische Aspekte, Daten- und Kontrollflüsse)
- Verteilungssicht (technische Infrastruktur, Verteilung von Laufzeitelementen)
Damit ist der Architekt in der Lage, die Architektur mit allen Beteiligten, vom Manager bis zum Administrator, zu diskutieren.
Überprüfung der Architektur
Die Verfeinerung der Architektur erfolgt in Zyklen. Dabei ist zu beachten, dass vor Beginn eines weiteren Zyklus die bestehende Architektur überprüft werden muss. Die folgenden Fragen gilt es dabei u.a. zu beantworten:
- Haben sich die Anforderungen geändert oder sind neue hinzugekommen?
- Passt die aktuelle Architekturnoch zu den Anforderungen?
- Sind die Anforderungen an die (aus der Zerlegung entstandenen) Kind-Module klar?
- Sind die Schnittstellen zu den Kind-Modulen klar?
- Muss ein Modul noch weiter verfeinert werden?
Die Überprüfung der Architektur sollte in Zusammenarbeit mit den Interessenvertretern durchgeführt werden, weshalb auch der o.g. Dokumentation eine wichtige Bedeutung zukommt.
Ergeben sich aus der Überprüfung Änderungen oder Neuerungen, so muss der beschriebene Prozess bzgl. der veränderten Anforderungen (ggf. auch beginnend von der Betrachtung des Systemkontextes) wiederholt werden.
Fazit
Mit diesem Artikel wurde ein möglicher Weg aufgezeigt, wie der Softwarearchitekt eine tragfähige Softwarearchitektur entwickeln kann.
Es bleiben eine Reihe spannender Fragen, die eine detaillierte Betrachtung wert sind. Dazu gehören neben dem Risikomanagement und der Dokumentation auch Einzelheiten zu Architekturmustern und -stilen sowie das Vorgehen bei der Bewertung von Qualitätsszenarien. Das Thema der Abbildung der Architektur auf konkrete Technologien und das Vorgehen bei der Architekturentwicklung in agilen Projekten sind ebenfalls umfangreich genug, um sie gesondert zu behandeln.
Die Softwarearchitektur ist eine umfangreiche und weitverzweigte Disziplin und wird noch genügend Stoff für weitere Beiträge an dieser Stelle liefern.