Wartung und regelmäßige Erneuerung der Softwarearchitektur verhindern große technische Schulden

Technische Schulden und warum regelmäßige Refactorings so wichtig sind
Keine Kommentare

Nahezu jeder Entwickler kennt es: Zeitmangel und Druck führen dazu, Schleichwege und Abkürzungen zu gehen, die einen immer weiter vom Projektentwurf entfernen. Regelmäßige Refactorings scheitern oft bereits an den Voraussetzungen. Der „quick and dirty way“ wird wegen des üblichen Zeitdrucks der sauberen Lösung vorgezogen und die Probleme in die Zukunft verschoben. Auch wenn Änderungen für das Gelingen eines Projekts teils notwendig sind, führen sie doch allzu häufig zur Erosion der Architektur und verursachen kaum noch zu bewältigende technische Schulden.

Die technische Schuld selbst beschreibt zunächst den zeitlichen Mehraufwand, den „schlecht“ geschriebene bzw. technisch unvorteilhaft umgesetzte Software gegenüber „gut“ geschriebener Software dem Entwickler und dem Product Owner abverlangt. Diese metaphorischen Schulden müssen irgendwann mit Zinsen (das ist der Mehraufwand) abgetragen werden. Das können in der Praxis Implementationsschulden, Testschulden, Dokumentationsschulden Design- oder Architekturschulden sein. Häufig sind es die kleinen Unachtsamkeiten oder Abweichungen vom Standard, nicht die riesengroßen Bugs, die meist erst bei der Projektübernahme eine gefühlte Backlog-Explosion verursachen.

Es geht bei technischen Schulden im Endeffekt immer um die Frage, was getan werden muss, damit eine Software eine möglichst hohe Wartbarkeit und fachliche Flexibilität aufweist: Das Ziel muss es also sein, „langlebige Softwarearchitekturen“ zu kreieren.

Jede Softwarearchitektur hat technische Schulden

Jedes Projekt, auch die „kerngesunden“, müssen mit technischen Schulden umgehen. Es gilt zu verhindern, dass sich diese Schulden zu einem unüberwindbaren Berg anhäufen und die Entwickler ab einem bestimmten Punkt nur noch damit beschäftig sind, das weitere Anwachsen des Schuldenbergs zu verringern.

Zur Einführung ins Thema und einer Übersicht der verschiedenen Arten technischer Schulden lohnt sich einerseits der Artikel „Technische Schulden als Entscheidungsgrundlage: Wie Product Owner und Entwickler für langlebige Architekturen sorgen“ von Dr. Carola Lilienthal sowie das Interview mit ihr, in dem sie thematisiert, wie man technische Schulden wieder los wird:

Einfache und konsistente Softwarearchitektur

Die optimalen Voraussetzungen für eine funktionierende und saubere Softwarearchitektur werden jedem Entwickler geläufig sein. Zu häufig sieht es in der Praxis aber aus verschiedenen Gründen ganz anders aus. Das System sollte durchgängig modular und die Hierarchien sinnvoll angeordnet und nicht unverständlich vermischt sein. Ebenso müssen die Muster eine durchgängige Konsistenz aufweisen. In neuen Bibliotheken oder Anwendungen muss eine strikte Haltung gegenüber technischer Schulden durchgesetzt werden.

Das alles ist dem Ziel geschuldet, Entwickler schneller und effizienter arbeiten zu lassen. Weil der Mensch laut den Erkenntnissen der Psychologie Informationen über sogenannte Chunks aufnimmt und zu größeren Blöcken zusammenfasst, sind intuitiv verständliche, am besten einheitliche, zusammenhängende und simple Architekturkonzepte das, was entwickelt werden sollte, um die angestrebte Effizienz zu erzielen.

Ebenso sollte sich das Team auf bevorzugte Patterns, Frameworks und Technologien einigen – im Idealfall natürlich vor dem Projektstart.

Den Product Owner für sich gewinnen

Dem Kunden und Product Owner muss veranschaulicht werden, was technische Schulden sind, wie sich lösen lassen und welche Vorteile das mit sich bringt. Erst wenn der Product Owner wirklich begreift, warum frühzeitige, zyklische Refactorings auch der Schlüssel zum betriebswirtschaftlichen Erfolg sind, kann hier ein Umdenken stattfinden. Vorausgesetzt ist hier immer, dass die Kosten des Refactorings unter denen der technischen Schulden liegen und sich das Refactoring langfristig auszahlt. Erst wenn klare Regelungen mit dem Product Owner bzw. dem Management vereinbart sind und das jeweilige Verständnis stimmt, kann geschlossen und effizient gegen die technischen Schulden gearbeitet werden.

Gerrit Beine hat das Verhältnis der Product Owner zur marktwirtschaftlichen Bedeutung technischer Schulden und den Refactorings treffend umschrieben:

„Es geht nicht mehr um State-of-the-Art- oder Framework-Versionitis, sondern darum, ob das Projekt von der Beseitigung der technischen Schuld profitieren. Gleichzeitig wird durch die kontinuierliche Betrachtung die Existenz der technischen Schulden immer wieder bewusst gemacht, sodass sie nicht in Vergessenheit geraten. Die Kosten des Nichthandelns erzeugen einen gewissen Druck, nicht immer nur Funktionalität hoch zu priorisieren.“

Was gegen technische Schulden zu tun ist

Man sagt, dass jede Softwarearchitektur mit der Zeit Jahresringe bekommt. Nur wie groß diese Ringe sein müssen und wie stark sie ausgeprägt sind, ist nicht per se festgelegt. Der Grad der Wartbarkeit wird durch regelmäßige Architektur-Erneuerungen hochgehalten. Was dringend vermieden werden sollte, ist eine Erosion der Architektur, die nur noch durch anstrengende, große Refactorings behoben werden kann. Und je weiter eine Architektur erodiert, desto ineffizienter gestaltet sich die Arbeit mit ihr, während gleichzeitig immer mehr Geld investiert werden muss.

Abhilfe kann mit regelmäßiger Wartung und Erweiterung der Architektur geschaffen werden. Von Anfang an sollte man auf die strukturelle Einfachheit und Konsistenz des Codes achten. Wer kontinuierlich an seinen technischen Schulden arbeitet, kann die nötigen Feature-Implementierungen, Bug-Fixes und die branchenübliche Innovationsgeschwindigkeit besser bewältigen. Dazu gehören die regelmäßige Visualisierung der Fehler und die Kontrolle der Entwicklungsumgebung. Solange man diese Ratschläge befolgt, bewegt man sich im Bereich geringer technischer Schulden und hat alles richtig gemacht.

Refactoring: Regelmäßige Wartung und Erneuerung

Es kommt auch darauf an, den verantwortlichen Mitarbeitern die nötige Zeit zu geben, auf Änderungen, Bug-Fixes und sonstiges zu reagieren, um den Aufbau technischer Schulden möglichst gering zu halten. Regelmäßige Wartung und Erneuerung können vor großem Refactoring bewahren und für eine immense Erleichterung sorgen. Prokrastination sollte tunlichst vermieden werden und technische Schulden nicht gewohnheitsmäßig im Backlog abgelagert werden. Mit Ritualen und klaren Zielsetzungen lässt sich hier viel erreichen.

Laut Jeroen Moons lässt sich so ein Sumpf in eine prachtvolle grüne Wiese verwandeln. Wer kleine aber zyklische Schritte geht und sich realistische Aufgaben stellt, komme schneller als Ziel als derjenige, der sich gleich auf die größten Baustellen stürzt. Das heißt im Klartext: Beim Refactoring muss sich vom simplen zum komplexen Problem hochgearbeitet werden. Perfektionismus ist hier der falsche Ansatz. Effizienter ist es, die wichtigen, kleinen Baustellen einer sinnvollen To-Do-Liste Schritt für Schritt mit einem guten Ergebnis abzuarbeiten – Perfektion gibt es in der Softwareentwicklung nicht.

Moore rät davon ab, Code gänzlich neu zu schreiben. Bis zum finalen Einsatz könne er nämlich nicht nur schwer seine Tauglichkeit beweisen, parallel zum alten Projekt einen bestimmten Teil davon neu zu generieren, koste auch immens viel Zeit und führe letztlich nur dazu, dass alte Fehler wiederholt würden.

Tools zur Architekturanalyse verwenden

Ein Soll-/Ist-Vergleich der Architektur kann mit nützlichen Architekturanalyse-Tools erreicht werden. Eine statistische Analyse der technischen Qualität des vorhandenen Quellcodes kann in vielen Fällen sehr hilfreich sein. Empfehlenswerte kostenlose Tools sind zum Beispiel SonarQube, JDepend, Ndepend/CDepend oder XRadar.

Höherwertige Architekturschulden sind jedoch mit solchen Tools schwierig zu analysieren. Die Tools arbeiten mit einem vordefinierten Satz an Regeln und Grenzwerten, der natürlich nicht immer einheitlich ist oder exakt auf die Problemstellen des eigenen Quellcode zugeschnitten ist.

Automatisierte Tests einrichten

Essenziell sind automatisierte Tests und Continuous Integration im Sicherheitsnetz der Softwarearchitektur. Immer wieder schnell überprüfen zu können, ob nach einer Änderung noch alles rund läuft, macht die automatischen Tests so wichtig – ansonsten könnten auch manuelle Tests herhalten. Sobald ein Bug auftritt kann er mit einem neu geschriebenen automatisierten Test langfristig verhindert werden.

Unter der Prämisse nicht alles zu testen, sollten eigenständig isolierte Code-Fragmente High-Level- oder Low-Level-Tests bzw. Unit-Tests unterzogen werden. Entsprechende Codeschnipsel kann man nach der klassischen Methode isolieren und ersetzen.

Zum Schluss empfehlen wir den interessanten Vortrag von Dr. Carola Lilienthal, der das Thema langlebiger Softwarearchitekturen und wie sich technische Schulden vermeiden lassen, vertiefend behandelt:

Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -