Surprise!

Zeitgemäße Softwarearchitektur: Förderung von und Umgang mit Überraschungen

Stefan Toth

© Shutterstock/pzAxe

Im ersten Teil der Serie ging es um Praktiken, die beim Umgang mit begrenztem Geld- oder Zeitbudget auf Architekturseite wichtig sind. In diesem Teil schwenkt die Aufmerksamkeit auf den zweiten wichtigen Punkt zeitgemäßer Softwarearchitektur: Überraschungen. Erfolgreiche Projekte setzen auf häufige Überraschung aus der Umsetzung und scheitern immer wieder in kleinem Umfang. Der Weg führt über priorisierte Architekturanforderungen, mit der Entwicklung verzahnte Architekturarbeit und das Konzept der technischen Schulden.

Ein Freund von mir lädt öfter Mal Filme aus dem Netz (ich kenne ihn eigentlich kaum). Liegen die Kinoneuheiten nicht im AVI- oder MP4-Format vor, kann sein am Fernseher angeschlossener Mediaplayer sie nicht abspielen – er muss nach dem Download rekodieren, die Datei dann auf seine externe Festplatte kopieren und kann schließlich von dieser streamen. Der Prozess kann einige Stunden in Anspruch nehmen. Natürlich kann man diese Kette optimieren und modernisieren, aber mein Punkt ist ein anderer: Wann würden Sie herausfinden wollen, ob die Video- und Audioqualität annehmbar ist, ob die Sprache passt und ob die A/V-Synchronisierung stimmt? Am Ende der Verarbeitung, am Fernseher? Vor dem zeitaufwändigen rekodieren am Computer? Am besten doch noch vor dem Download, also sehr früh. Eine kleine Streaming-Preview hilft bei der Wahl der richtigen Filmversion und spart Stunden (sagt der Freund).

Artikelserie
Teil 1: Beschränkte Mittel
Teil 2: Förderung von und Umgang mit Überraschungen

Auch wenn Sie (so wie ich) nichts mit illegalen Filmdownloads zu tun haben: Früh nach Erkenntnis und Wahrheit zu suchen, ist intuitiv und normal. Es spart Zeit. Sie wollen nicht lange in die falsche Richtung laufen, vermeidbare Irrwege früh erkennen. Warum sollten wir in der Arbeit an Softwarearchitektur anders handeln? Eine Architekturvision, konzeptionelle Entscheidungen oder entworfene Schnittstellen und Anwendungsstrukturen sind zuallererst nur eine Idee. Ob diese Ideen gut und tragfähig sind, kann erst auf Codeebene und mit entsprechenden Tests abschließend beantwortet werden. Irgendwann kommt jedes Projekt zu diesem Punkt: „Jetzt wissen wir, wie wir es hätten machen sollen“. Architekturentscheidungen schlagen mit der Zeit jedoch immer tiefere Wurzeln in einer Applikation. Wir sollten also danach streben, möglichst bald belastbares Feedback zu Architekturarbeit zu bekommen – und uns davon in kleinen Häppchen überraschen lassen.

Kleine Überraschungen >= breite Analyse
Sie haben immer wieder wichtige Entscheidungen in Ihrem Projekt zu treffen. Nehmen wir zum Beispiel an, ein Teil Ihrer Applikation nimmt komplizierte Berechnungen vor. Sie haben bereits Bausteine definiert und sehen sich nun mit Anforderungen konfrontiert, die hohe Flexibilität im Berechnungsablauf fordern. Da die Fragestellung nicht isoliert betrachtet werden kann und viele Bausteine betrifft, wollen Sie vor der Umsetzung eine Lösung entwerfen. Um möglichst lose Kopplung zu erreichen, sehen Sie einen einfachen Eventmechanismus vor. Komponenten sollen einen eigenen Berechnungszustand halten und bei Änderungen an diesem Zustand Events feuern. Andere Bausteine können auf diese Events reagieren. Sie erstellen eine kleine Implementierung, die Möglichkeiten Ihrer Plattform nutzt, um diese Idee umzusetzen. Es funktioniert. An dieser Stelle definieren Sie die Idee als brauchbare Möglichkeit und entscheiden sich für die Umsetzung. In der Umsetzung wenden Sie das Konzept auf Ihre Bausteine an (vielleicht nicht sofort auf alle). Sie versuchen Zustandsübergänge zu definieren, eine produktivtaugliche Implementierung für den Zustand selbst zu kreieren und entwerfen fachliche Events. Erst hier haben Sie das Problem annähernd vollständig vor Augen: Sie erkennen, wie kompliziert sich Zustände teilweise zusammensetzen, welche Daten mit den Events übertragen werden müssen und wie diese Lösung mit anderen Konzepten Ihrer Bausteine zusammenwirkt. Haben Sie wichtige Teile umgesetzt, können Sie mit Tests eine Idee vom Laufzeitverhalten bekommen. Hier ist ein wichtiger Berührungspunkt zwischen Architektur und Implementierung: die Rückmeldung aus der Implementierung samt den Erkenntnissen aus Integration und Test. Erhalten Sie diese Rückmeldung oft und kleinteilig, werden Sie bessere Architekturarbeit leisten. Sie erden Architekturentscheidungen in der realen Welt und minimieren den Raum für Annahmen und Spekulationen.

Werfen Sie alle Architekturfragen am Anfang des Projekts auf und entwerfen sogleich Lösungen auf diese Fragen, dauert es tendenziell länger, bis einzelne Lösungsideen in der Implementierung umgesetzt sind. Arbeiten Sie kleinteiliger, zeitlich gestreckt, können Sie schnelleres Feedback garantieren und profitieren bei der Bearbeitung des nächsten Architekturthemas von Ihren Erkenntnissen beim vorherigen.

Ja, das ist „einfach nur“ iteratives Vorgehen, jedoch gehört zu iterativer Architekturarbeit mehr, als üblicherweise in der Praxis gelebt wird. Zunächst müssen Sie Ihre Architekturarbeit „stückeln“ können, also in eine Serie von relativ unabhängigen Architekturfragestellungen und -entscheidungen verwandeln. Das wiederum erfordert explizite Arbeit mit Architekturanforderungen und eine Idee, wie diese Anforderungen priorisiert werden können. Auch Architektureigenschaften im Code der Implementierung zu überprüfen, ist wichtig und, damit das stetig und möglichst früh erfolgt: häufig lauffähige Software von Beginn an. Schließlich ist ein Konzept hilfreich, das aufgedeckte Probleme und als falsch erkannte Entscheidungen bearbeitbar macht. Technische Schulden sind auch auf Architekturebene ein gutes Denkkonstrukt. Sie tragen der Tatsache Rechnung, dass nicht jedes Problem projektgefährdend ist und sofort oder vollständig beseitigt werden muss. Tabelle 1 zeigt diese Themen noch einmal strukturiert.

Aufgabe Konzepte
Förderung früher Überraschungen Iteratives Vorgehen, keine „Disziplinensilos“, Continuous Integration
Priorisierte Architekturanforderungen Szenarien, Risikobewertung, der letzte vernünftige Moment (LVM)
Überraschungen und Probleme explizit bearbeiten Technische Schulden

Tabelle 1: Aufgaben zum Umgang mit Überraschungen (Ausschnitt der Übersichtstabelle in Teil 1 der Artikelserie)

Förderung früher Überraschungen

Zwischen einer Architekturentscheidung und der Rückmeldung aus der Umsetzung sollte wenig Zeit verstreichen. Das gelingt am besten, wenn Sie wenige Architekturfragen gleichzeitig bearbeiten. Starten Sie mit einer schlanken Architekturvision, die Ihr Entwicklungsteam grundsätzlich arbeitsfähig macht. Abbildung 1 zeigt, was eine typische Architekturvision beinhalten kann. Erstellen Sie anschließend schon lauffähigen Code, der Rückschlüsse auf die ersten Architekturideen erlaubt.

Abb. 1: Typische Inhalte einer Architekturvision

In jedem Projekt werden Architektur- und Entwicklungsarbeit zusammenwirken. Beschränken Sie sich auf wenig Vorabarbeit, ist das noch mehr der Fall. Dynamische Projekte verrichten konzeptionelle Arbeit und Entwicklungsaufgaben verzahnt. Abbildung 2 illustriert diesen Sachverhalt grob und fokussiert auf die Berührungspunkte (In den letzten Jahren hat sich der Name „Architekturbrezel“ etabliert.).

Abb. 2: Die Architekturbrezel

Rechts ist der Umsetzungszyklus zu sehen, in dem der eigentliche Programmcode entsteht, Tests geschrieben und ausgeführt werden, sowie Softwareteile integriert und ausgeliefert werden. In diesem Zyklus entsteht Wert für den Kunden und wir bekommen hier auch unverrückbare Tatsachen zurückgespiegelt, die uns vielleicht überraschen, in jedem Fall aber lernen lassen. Sie wollen so viel Zeit wie möglich in diesem rechten Teil der Abbildung verbringen.
Im linken Teil von Abbildung 2 befindet sich der Architekturzyklus. Grundsätzliche fundamentale Fragestellungen wandern vor der Implementierung durch den Architekturzyklus, um das Risiko einer teuren Fehlentscheidung zu minimieren. Dort werden Prototypen und Modelle erstellt, technische Problemstellungen analysiert, Technologien evaluiert oder Schnittstellen entworfen (im Kasten „Kleine Überraschungen >= breite Analyse“ wird der Eventmechanismus in einem Architekturzyklus entworfen). Brauchbare Möglichkeiten und Architekturentscheidungen bieten die Grundlage für Implementierungstätigkeiten, sie stellen eine Vorgabe dar (Abb. 2, oben links). Es handelt sich um den ersten wichtigen Berührungspunkt zwischen Architektur- und Umsetzungsarbeit. Der zweite ist die Rückmeldung aus der Implementierung samt den Erkenntnissen aus Integration und Test (Abb. 2, oben rechts und Teil 1 dieser Serie). So prüfen Sie Architekturentscheidungen und minimieren den Raum für Annahmen und Spekulationen. Insgesamt entsteht eine gelebte Softwarearchitektur, die durch die Implementierung nicht verwässert, sondern bereichert wird.
Die beiden Berührungspunkte (Vorgabe und Rückmeldung) sollten möglichst eng beieinander liegen, um gut auf Überraschungen und Probleme reagieren zu können. Die erfolgreichsten Softwareprojekte, die ich begleitet habe, arbeiten in einem kontrollierten Trial-and-Error-Prozess. Sie haben eine technische Herausforderung zu lösen, wählen eine vielversprechende Lösungsoption und testen in einem fokussierten Umsetzungszyklus, ob sie hält, was sie verspricht. Ist der Test erfolgreich, bearbeiten sie die nächste Fragestellung und achten kontinuierlich darauf, dass das Gesamtkonzept noch trägt. Diese erfolgreichen Projekte erkennen oft, dass sie falsch liegen – sie werden oft überrascht. Im Gegensatz dazu stehen Projekte, die jahrelang „gut laufen“, beim ersten Auslieferungsversuch oft vor einem unüberwindbaren Berg an Problemen. Sie drehen mehrere, langsame Runden im Architekturzyklus und werden spät überrascht – dann aber richtig. Gerade bei Architekturarbeit ist die späte Überraschung teuer und projektgefährdend.

Continuous Integration

Es gibt einige Praktiken die helfen, Architektur- und Implementierungszyklus dynamisch in Austausch zu bringen. Früh ein lauffähiges System zu haben, ist in jedem Fall hilfreich. Hier kommt Continuous Integration ins Spiel: die zwei zentralen Konzepte sind (angelehnt an):

• Häufiges Commit: Änderungen erfolgen kleinteilig und werden häufig in die Versionsverwaltung übertragen. Als Daumenregel gilt: mindestens ein Commit pro Tag.
• Sofortiger Build: Änderungen in der Versionsverwaltung lösen einen Build aus, der das Gesamtsystem neu baut, automatisierte Tests ausführt, Qualitätsindikatoren und Architekturregeln prüft und entsprechende Reports generiert.

Die Ausführung von Tests, Qualitäts- und Regelprüfungen geschieht also oft und automatisiert. Neben Continuous Integration hat sich auch der Begriff Continuous Delivery etabliert, der zusätzlich zu Integration und Test auch die Auslieferung von Software in unterschiedliche Umgebungen inklusive der Produktivumgebung automatisiert [4]. Wenn man so möchte, denkt Continuous Delivery die Idee von Continuous Integration konsequent zu Ende. Oft bestimmt Ihre Domäne oder Basistechnologie, wie weit Sie gehen können. Im Embedded-Bereich oder bei teuren und außergewöhnlichen Produktivumgebungen ist Continuous Delivery schwieriger umzusetzen als bei Webapplikationen oder Cloud-Anwendungen. Die wichtige, frühe Rückmeldung aus entsprechenden Prüfungen gelingt meist mit Continuous Integration oder, mit Abstrichen, sogar mit Nightly Builds und halbautomatisierten Verfahren recht gut.
Abbildung 3 zeigt den Auslieferungsprozess etwas detaillierter. Im linken Bereich finden Sie den Kern von Continuous Intergration. Continuous Delivery automatisiert alles, was Sie auf der Abbildung sehen, wodurch eine so genannte Deployment Pipeline entsteht.

Abb. 3: Build, Test und Auslieferung im Überblick

Der Einstieg in Abbildung 3 ist links oben. Als Entwickler schreiben Sie Programmcode und Tests. Bevor Sie einchecken, führen Sie einen lokalen Build aus und testen die Anwendung auf Unit-Ebene. Sobald Sie Ihren Code in die Versionsverwaltung einchecken, beginnt ein zentraler Build- und Integrationsprozess. Continuous-Integration-Server übernehmen hier die Orchestrierung von Build, Tests, Analyse und Reporting. In dieser Commit Stage liegt der Fokus auf funktionalen Tests, Integrationstests und statischer Analyse. Erst nach erfolgreichem Durchlaufen dieser Phase wird der Commit als geglückt angesehen. Architekturell spannend sind dabei Metrikanalysen für Qualitätsindikatoren und Umsetzungsprüfungen aus Architekturregelwerkzeugen. Beides steht schnell als Feedback zur Verfügung.
Nach dieser ersten schnellen Phase (oder „Stage“) wird der weitere Prozess in Schritte unterteilt, die aufwändiger oder längerlaufend sind. Aus dem Repository werden Binaries an Umgebungen ausgeliefert, die möglichst genau der späteren Produktivumgebung entsprechen. Dort werden üblicherweise zunächst Akzeptanztests durchlaufen, bevor manuelle Tests und Testsuiten für Performanz, Last, Sicherheit etc. zum Einsatz kommen. Die Aufteilung dieser Aktivitäten in Stages ermöglicht zeitnahe Rückmeldungen, auch wenn nachfolgende Stages länger dauern, und bedeutet Kostenersparnis, wenn frühere Stages bereits fehlschlagen und damit aufwändigere Tests erspart bleiben. Moderne Continuous-Integration-Server machen staged builds relativ leicht möglich und lassen sich mit automatischen Deployment-Werkzeugen für Konfiguration und Auslieferung kombinieren. Reports werden automatisch aggregiert und machen die Verfehlung (architektonischer) Ziele analysierbar. Architekturregelwerkzeuge wie Sonar, Structure101 oder Sonargraph lassen sich ebenfalls gut integrieren und unterstützen zusätzlich.

Keine Disziplinensilos

Auch organisatorische Aspekte fördern eine Verzahnung von Architektur- und Umsetzungsarbeit. Ein Beispiel dafür ist die Auflösung so genannter Disziplinensilos, in denen sich Projektmitarbeiter auf genau eine Disziplin der Softwareentwicklung spezialisieren (etwa Anforderungsanalyse, Architektur, Entwicklung oder Test). Teamgrenzen zwischen einzelnen Disziplinen werden, befeuert durch Konzepte wie Stories und Backlogs oder Bewegungen wie DevOps, in den letzten Jahren weniger. Auch Architektur und Entwicklung werden auf Personalebene immer verwobener betrachtet. Das sorgt für besseres gegenseitiges Verständnis, weniger Kommunikationsschwierigkeiten (und Missverständnisse) sowie davon abgeleitet höhere Entwicklungsgeschwindigkeit. Es sind weniger Übergaben nötig und Architekturfragen wandern früh in die Hoheit derer, die sie letztendlich auch entscheidend beeinflussen: Entwickler. Überlegen Sie also gut, ob Sie getrennte Architekturabteilungen oder -teams brauchen. Viele moderne Architekturpraktiken, wie auch die in Teil 1 beschriebene Architekturbewertung oder die weiter unten beschriebene Arbeit mit Qualitätsszenarien, machen gemeinsame Architekturarbeit im Entwicklerkreis einfacher. Weitere Ideen finden Sie hier.

Priorisierte Architekturanforderungen

Auf Architekturebene sind Qualitätsanforderungen sehr oft ein Thema. Die Wahl zwischen verschiedenen technologische Plattformen, Frameworks oder Schnittstellenmodellen kann nur unzureichend mit funktionalen Unterschieden erklärt werden. Eher sind Unterschiede in der Stabilität, der Wartbarkeit oder im Laufzeitverhalten zu beobachten. Diese Anforderungen bzw. Probleme bei der Erreichung dieser Anforderungen sollten Architekturarbeit treiben. Voraussetzungen dafür sind:

• Konkrete Aussagen zu nicht funktionalen Aspekten
• Eine Möglichkeit, diese Aussagen zu priorisieren
• Ein Konzept, um architektonische Probleme auf Anforderungen zurückzuführen

Der letzte Punkt ist mit dem Konzept der technischen Schulden realisierbar (mehr dazu weiter unten). Die ersten beiden Punkte können mit den in Teil 1 vorgestellten Qualitätsszenarien erreicht werden. Sie stellen konkrete Beispiele für Qualitätsanforderungen dar und können auch in agilen Backlogs verwendet werden. Ein Szenariobeispiel für Wartbarkeit wäre: „Der Algorithmus zur Berechnung der Artikelbeliebtheit soll leicht anpassbar und austauschbar sein“.

Qualitätsszenarien priorisieren

Um Szenarien in einer priorisierten Anforderungsliste wie einem Backlog zu verankern, gibt es zwei Möglichkeiten: Sie können die Qualitätsszenarien wie Stories unabhängig in den Backlog legen oder sie einzelnen funktionalen Anforderungen zuordnen. In der Praxis ist beides sinnvoll: Obiges Szenariobeispiel ist am besten bei der funktionalen Anforderung zur Berechnung der Artikelbeliebtheit aufgehoben und wird gemeinsam mit dieser Anforderung priorisiert. Andere Szenarien, die Sicherheit oder Zuverlässigkeit zum Thema haben, beziehen sich oft nicht auf einzelne Funktionalitäten, sondern betreffen das gesamte System oder weite Teile desselben. Diese Szenarien sind die aus architektonischer Sicht wichtigeren und werden mit der „normalen“ Suche nach Akzeptanzkriterien zu funktionalen Anforderungen schwer gefunden. Fragen Sie sich deshalb:

• Für Benutzbarkeit und Effizienz: Was soll bei normaler Nutzung des Systems spürbar sein?
• Für Skalierbarkeit, Erweiterbarkeit und Übertragbarkeit: Wo und wie entwickelt sich das System weiter?
• Für Zuverlässigkeit, Sicherheit und Lastverhalten: Wie reagiert das System auf unvorhergesehene Ereignisse?

Gefundene Szenarien, die unabhängig in die Anforderungsliste aufgenommen werden können, müssen priorisiert werden. In neu gestarteten Projekten sollte möglichst schnell ein „walking skeleton“ entstehen – ein Gerüst der Anwendung, das alle kritischen Schichten und Technologien berührt, ohne viel „Fleisch“ (im Sinne von Funktionalität) zu bieten. Technologisch herausfordernde oder neue Anforderungen und Szenarien werden folglich höher priorisiert als Anforderungen, die architektonisch mehr vom selben sind. In späteren Projektphasen ist vor allem das architektonische Risiko entscheidend. Folgende Fragen liefern Hinweise auf die Höhe des Risikos:

• Wie teuer oder zeitaufwändig wäre eine Fehlentscheidung zu revidieren?
• Wie viele Projektmitglieder sind von der Entscheidung betroffen?
• Sind zentrale Ziele des Projekts mit der Fragestellung verknüpft?

Szenarien mit hohem architektonischen Risiko wandern weiter oben in die Anforderungsliste. Die verwobene Liste kann anschließend mit der Architekturbrezel (Abb. 2) verarbeitet werden.

Der letzte vernünftige Moment

Der letzte vernünftige Moment stellt eine weitere Priorisierungshilfe dar. (Architektur-)Entscheidungen werden dabei möglichst spät getroffen, auch wenn das Problem (Szenario) selbst schon früher bekannt ist. Hören Sie dieses Konzept zum ersten Mal, klingt es vielleicht eigenartig oder gewöhnungsbedürftig, die Grundidee ist jedoch einleuchtend: Wann wissen Sie das Meiste über ein Softwareprojekt? Wahrscheinlich wenn es abgeschlossen ist. Mit dem Wissen am Ende eines Projekts könnten Sie das gleiche Problem wohl in der Hälfte der Zeit lösen. Sie würden weniger Mitentwickler benötigen und manche Entscheidungen anders treffen. „Hinterher ist man immer klüger“ hört man Leute sagen. Die Klugheit kommt allerdings nicht auf einen Schlag zu Projektende. Sie wächst über den gesamten Projektverlauf.
Die meisten Entscheidungen lassen sich nicht beliebig weit nach hinten schieben. Irgendwann gibt es einen Punkt, an dem eine Entscheidung spätestens getroffen werden muss, um negative Effekte zu vermeiden. Diesen virtuellen Moment nennen wir den „letzten vernünftigen“. Zwischen dem Erkennen der Fragestellung und dem letzten vernünftigen Moment, öffnet sich ein Lernfenster. In diesem Fenster steigt das Wissen über das Problem und wichtige Rahmenbedingungen stetig. Sie sollten versuchen, diesen Lernzeitraum so groß wie möglich zu machen und aktiv zu nutzen. Lernen Sie durch Ausprobieren, Testen, Klärung und eventuell auch Umsetzung von Alternativen. Sie treffen so informierte und tendenziell bessere Entscheidungen.
Vielleicht fragen Sie sich gerade, warum das Verschieben von Architekturentscheidungen frühe Überraschungen fördern soll. Konkret gibt es zwei Gründe dafür:

• Durch die Verschiebung bleibt mehr Zeit für jene Architekturfragen, die schon früh im Projekt am letzten vernünftigen Moment sind. Diese können dann konzentriert angegangen und mit Rückmeldungen aus der Entwicklung versorgt werden, bevor andere Fragen ablenken.
• Frühe Überraschung bedeutet auch, dass zwischen der Entscheidung und der Rückmeldung wenig Zeit verstreicht. Genau genommen optimiert der letzte vernünftige Moment diese Zeiträume. Sie warten mit der Entscheidung möglichst lange, setzen dann aber zeitnah um.

Technische Schulden

Ich habe nun grob umrissen, wie Anforderungen detailliert und priorisiert werden können, um eine echt iterative Arbeit an Softwarearchitektur zu ermöglichen und möglichst zeitnah Rückmeldung zu architektonischen Konzepten zu bekommen. Wie gehen Sie jedoch mit dieser Rückmeldung um? Kann die laufende Applikation Ihre Vermutungen bestätigen und liefern Tests positive Erkenntnisse, können Sie die dahinter stehenden Architekturentscheidungen annehmen und breit umsetzen. Komplizierter wird es, wenn sich Probleme offenbaren. Hier kommt das Konzept der technischen Schulden ins Spiel.

Mehr zum Thema

Diese Artikelserie basiert auf Stefan Toths Buch „Vorgehensmuster für Softwarearchitektur“, das im Carl Hanser Verlag erschienen ist. Eine Rezension dazu finden Sie im Java Magazin 4.2014 auf Seite 10.

Technische Schulden werden oft auf Design- und Entwicklungsebene betrachtet, sind aber als Konzept viel breiter und gut auf Architekturversäumnisse anwendbar. Tatsächlich sind sich technische Schulden und Architekturanforderungen nicht unähnlich. Wie Architekturanforderungen können technische Schulden einen Bedarf an Architekturarbeit aufdecken. Das passiert allerdings zu einem Zeitpunkt, an dem bereits Umsetzungsarbeit geleistet wurde und die nötigen (Architektur-)entscheidungen, bewusst oder unbewusst, verpasst oder falsch getroffen wurden.
Decken Sie in der Umsetzung nicht optimal getroffene Architekturentscheidungen, fehlende Prinzipien, nicht eingehaltene und verwässerte Architektur auf, haben Sie eine Schuldenlast zu tragen. Einiges davon wird, genau wie Codeschulden, stetig bezahlt (verwässerte Architektur und Inkonsistenzen), andere Architekturschulden zeigen sich durch eine immer teurer werdende „wirkliche“ Lösung aus. Arbeiten Sie momentan etwa auf einer Systemkonfiguration, die unpassend für den Produktionsbetrieb ist, können Sie weiterhin Funktionalität entwickeln oder auch nicht funktionale Tests durchführen – je später Sie aber die tatsächlich nötige Umgebung wechseln, desto teurer wird der Umstieg (alleine weil die Menge an zu übertragenden Artefakten höher ist). Die Schulden steigen also „im Stillen“. Ähnlich verhält es sich mit halbherzig getroffenen Entscheidungen wie der Idee, Portierbarkeitsanforderungen alleine durch den Einsatz von Java vollständig gelöst zu haben. Allgemein können die folgenden Probleme technische Schulden auf Architekturebene anzeigen:

• Inkonsistenzen
• Redundanzen
• Unrealistische Lösungen (unpassend zu aktuellen Qualitätsmerkmalen oder Rahmenbedingungen)
• Trivialaufwände (Stellen, die viel triviale Arbeit erfordern)
• Sonderlösungen
• Fehlende Richtlinien (leitende Prinzipien oder rahmengebende Entscheidungen)
• Fehlender Überbau (allgemeine Lösungen, Frameworks, Kommunikationsinfrastruktur etc.)

Nicht alle gefundenen technischen Schulden verdienen eine Behandlung. Sie haben drei Handlungsoptionen:

Schuldenfortzahlung: Sie bearbeiten das Problem nicht weiter, sondern akzeptieren es (Null-Entscheidung).
Schuldenrückzahlung: Sie beseitigen die Schuld durch Umstrukturierungen, Migration, Portierung etc.
Umschuldung: Sie ersetzen die momentane Lösung mit einer guten, aber nicht perfekten Lösung, die eine geringere Schuldenlast verursacht (aber billiger ist als die komplette Schuldenrückzahlung).

Um zu entscheiden, welche dieser Taktiken die passendste ist, sollten Sie die Schuld fachlich ausdrücken. Definieren Sie Qualitätsszenarien, die durch die Beseitigung der Schuld erreicht werden könnten. Diesem (auch durch Nichtentwickler nachvollziehbaren) Nutzen stehen die Kosten der Schuldenrückzahlung oder Umschuldung gegenüber. Die Qualitätsszenarien sind priorisierbar und erkannte Probleme werden zu einem sekundären Architekturtreiber, der mit „normalen“ Anforderungen gleichsetzbar ist.

Fazit

In der vorliegenden Artikelserie habe ich Praktiken vorgestellt, die eine zeitgemäße Architekturdisziplin ausmachen, eine Disziplin, die sowohl auf begrenztes Geld- oder Zeitbudget reagiert als auch mit Überraschungen umgehen kann. Die Komplexität heutiger Softwareprojekte macht Überraschungen in der Umsetzung und Auslieferung zum Standard, nicht zur Ausnahme. Die in diesem Teil besprochenen Praktiken zeigen, wie Sie diese Überraschungen kleinteilig und häufig fördern können und sie so handhabbar machen. Das Konzept des letzten vernünftigen Moments verschafft Ihnen dabei den Freiraum, den Sie brauchen.
Teilweise konnte ich im Rahmen der Artikel besprochene Praktiken nur anschneiden und habe darauf fokussiert, ein Gesamtbild zum Zusammenspiel zu vermitteln. Detailliertere Informationen finden Sie im Web und in Buchform.

Aufmacherbild: The tops of skyscrapers against the sky von Shutterstock / Urheberrecht: pzAxe

Geschrieben von
Stefan Toth
Stefan Toth
Stefan Toth arbeitet als Entwickler, Softwarearchitekt und Berater bei der embarc GmbH. Seine Schwerpunkte liegen in der Konzeption und der Bewertung mittlerer bis großer Softwarelösungen sowie der Verbindung dieser Themen zu agilen Vorgehen. Er ist Autor zahlreicher Artikel und des Buchs "Vorgehensmuster für Softwarearchitektur". Kontakt: st@embarc.de
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: