16. Jun 2025
Lesedauer 7 Min.
Die Rückzahlung
Analysieren und zeitnah angehen
Schulden in der Softwareentwicklung können schnell zu großen Bergen anwachsen – die es irgendwann wieder abzubauen gilt. Wie das gehen kann, zeigt dieser Artikel.

Seien wir realistisch: In jedem Projekt sammeln sich im Lauf der Zeit verschiedene Arten von Schulden an: technische, strukturelle, dokumentarische und so weiter. Und wie finanzielle Schulden müssen diese irgendwann wieder „zurückgezahlt“ werden. Doch anders als in der Finanzwelt gibt es in der Softwareentwicklung keine Bank, die diesen Vorgang für uns regelt. Niemand zwingt uns zur Rückzahlung, und so können diese Schuldenberge immer weiter wachsen. Dadurch verschlechtern sich jedoch zahlreiche Parameter wie die Entwicklungsgeschwindigkeit, Fehleranzahl, Erweiterbarkeit oder Wartbarkeit immer weiter, bis das Projekt zum Stillstand kommt. Damit Ihnen das nicht passiert, sollten Sie vier wichtige Phasen beachten.
Phase 1: Die Ursache abstellen
Wie im vorangegangenen Beitrag [1] gezeigt, ist es essenziell, nach der Ursache technischer Schulden zu suchen. Jede erzeugte technische Schuld hat einen oder mehrere Fehler zur Ursache, und solange diese nicht abgestellt werden, ist die Wahrscheinlichkeit groß, dass weiterhin technische Schulden erzeugt werden. Es geht hier also weniger um Fingerpointing als um das Erkennen von Fehlern als Grundlage dafür, aus diesen zu lernen. Dieser aus der agilen Welt als „Continuous Improvement“ bekannte Ansatz ist das Fundament moderner qualitativer Entwicklung und sollte immer ganz am Anfang stehen. Solange dieses Mindset in Ihrem Entwicklungsteam und im gesamten Unternehmen nicht etabliert ist, wird es schwer, Schulden zu bekämpfen.Phase 2: Buchführung
Wenn ich in meinen Projekten mit verschiedenen Teams zusammenarbeite, ist sich meist jedes Team bewusst, dass im Projekt eine gewisse Menge von Schulden existiert. Häufig ist aber nicht nur die Art der Schulden unbekannt, sondern auch deren ungefähre Höhe. Das ist ein Umstand, der meistens entweder auf das Fehlen eines Softwarearchitekten im Team hinweist oder auf eine nicht korrekte Durchführung dieser Rolle. Als Softwarearchitekt ist meine Verantwortlichkeit weniger funktionaler Natur – wie beim Entwickler –, sie gilt vielmehr der Struktur. Der Architekt verantwortet über die Struktur eines Softwareprojekts dessen Langlebigkeit – er garantiert, dass mit dem Softwareprodukt langfristig Umsatz erzielt werden kann. Diese Langlebigkeit wird von verschiedenen Faktoren bedroht, aber keiner hat so starken Einfluss wie die im Projekt erzeugten Schulden verschiedenster Art. Aus diesem Grund ist es erforderlich, dass der Softwarearchitekt diese Schuldenarten im Projekt analysiert, überwacht und eine Strategie für ihre Abarbeitung erarbeitet.Zur Analyse der Schulden ist es zunächst notwendig, die Ist-Situation zu beschreiben. Zur Erinnerung: Schulden sind immer die Differenz zwischen Ist- und Soll-Situation. Gibt es in einem Projekt also keine Vorgaben bezüglich Softwarearchitektur, -design, Testen und so weiter, ist es auch nicht möglich, die Schulden zu dieser Ist-Situation zu ermitteln. In diesem Fall spricht man von den gefühlten Schulden (perceived debt). Das Erkennen solcher gefühlter Schulden ist bereits ein erster wichtiger Schritt auf dem Weg zu guter Software, wirklich damit arbeiten kann man jedoch nicht. Daher ist es zwingend erforderlich, eine solche Ist-Situation zuvor zu erarbeiten und danach schrittweise die Differenz zwischen Soll und Ist zu ermitteln. Dazu gibt es verschiedene Techniken, die oft in Kombination verwendet werden.Mit Tools wie NDepend (.NET), JArchitect (Java), CppDepend (C++) oder ScanYP (Python) können eine entworfene Architektur und Vorgaben für das Softwaredesign mittels Regeln abgebildet werden, die anschließend gegen das Softwareprojekt evaluiert werden können. Für jede Regel wird dabei festgelegt, wie viel Zeit für die Behebung der Regelverletzung erforderlich ist. Das Tool wertet dann alle Regeln aus, in einem großen Projekt meistens mehrere Hundert, und für die oft Tausende von Regelverstößen werden die technischen Schulden ermittelt und zu einem finalen Wert aufsummiert. Damit hat man natürlich nur näherungsweise eine Aussage über die tatsächliche Höhe der Schulden (technische Schulden, strukturelle Schulden), jedoch ist dies meist ein Wert, mit dem man bereits sehr gut arbeiten kann.Eine weitere Technik ist das sogenannte Debt Backlog, das in einem Tool wie Azure DevOps, Jira oder anderen Ticketsystemen gepflegt werden kann. Dabei geht es um eine Liste von Aufgaben, die zur Erreichung der Ist-Situation abgearbeitet werden müssen. Die gerade beschriebenen Tools können nicht alle Schulden und auch nicht alle Schuldenarten automatisch erfassen. Alle anderen werden im Debt Backlog festgehalten in Form von Tickets, die geschätzt werden und am Ende aufsummiert den zweiten Wert der Schulden ergeben. Inhalte solcher Tickets können aus verschiedenen Schuldenarten stammen: fehlende Dokumentation, fehlende Tests, Probleme im Prozess, größere strukturelle Fehler und Probleme, die durch Tools nicht erkannt werden können, anstehende Technologiewechsel und vieles Weitere. Oft werden solche Debt Backlogs nochmals aufgeteilt in verschiedene Schuldenarten.Am Ende werden dann die ermittelten Schulden aus allen Debt Backlogs und denen der eingesetzten Tools addiert, und so erhält man einen Schätzwert für die gesamten Schulden. Es sei erneut darauf hingewiesen, dass dieser Wert bestenfalls eine Näherung darstellt, für das Erarbeiten einer Abbaustrategie und deren Überwachung aber oftmals vollkommen ausreicht. Wie so oft ist auch hier die Pareto-Regel ziemlich zutreffend: 80 Prozent der Schulden lassen sich in 20 Prozent der Zeit ermitteln, für die restlichen 20 Prozent bräuchten Sie 80 Prozent der Zeit. Diese letzte Genauigkeit hilft aber oftmals niemandem wirklich weiter.Phase 3: Die Erkenntnis
Ist der Näherungswert ermittelt, ist das Entsetzen oft groß: Mit so hohen Schulden hatte niemand gerechnet. Neulich durfte ich ein 30 Jahre altes ERP-System untersuchen, das in einem „historisch gewachsenen“ Zustand war. Am Ende standen etwa 130 Personenjahre auf dem Beamer – das zehn Personen umfassende Entwicklungsteam benötigt also 13 Jahre, um diese Schulden abzuarbeiten. Wohlgemerkt ohne dabei neue Funktionalitäten zu entwickeln. Was das für ein Unternehmen bedeuten kann, überlasse ich Ihrer Fantasie. Wichtig ist jedoch: Diese Schulden sind da, sie sind real existent, wurden selbst verursacht und erzeugen immense Probleme. Es muss also eine Strategie her, wie diese oft gigantischen Schulden am besten abgearbeitet werden können.Phase 4: Die Strategie
Über viele Jahre die Implementierung neuer Funktionalitäten komplett einzustellen, um ein umfassendes Refactoring zu starten, ist natürlich in der Praxis so nicht umsetzbar – auch wenn ich es tatsächlich schon erleben durfte. In der Praxis steht am Anfang oft die Frage: Wie viel Prozent der Entwicklungsleistung können wir in Zukunft in den Abbau von technischen Schulden investieren? Hier kommt uns nun der ermittelte Schätzwert zugute, weil damit recht einfach gesagt werden kann: „Bei 20 Prozent Refactoring können wir die Schulden in acht Jahren abbauen.“ Dabei kann auch über neue Mitarbeiter diskutiert werden, die beim Refactoring unterstützen. So passiert es in meinen Projekten häufig, dass nicht nur bestehende Ressourcen für das Refactoring eingesetzt werden, sondern vor allem neue Mitarbeiter eingestellt werden, die direkt in die „neue Struktur“ eingearbeitet werden. Ist das Refactoring dann gestartet, gilt es das Ganze zu überwachen: Mithilfe der angesprochenen Tools und der Debt Backlogs kann beispielsweise monats- oder quartalsweise ermittelt werden, ob der Schuldenabbau wie geplant läuft oder ob es auf diesem Weg Probleme gibt.Der Profitipp
Ich habe in meiner Laufbahn bereits zahllose Analysen durchgeführt und die anschließenden Refactorings begleitet. Daher kenne ich diesen Schockmoment recht gut, wenn man zum ersten Mal das tatsächliche Ausmaß der Schulden sieht. Wichtig hierbei ist, das Problem nun nicht weiter zu ignorieren, sondern es zeitnah anzugehen. So gut wie immer ist jedoch das Hauptproblem: Es gibt keine Ressourcen für das Refactoring, weil das Projekt ohnehin bereits mit zahlreichen Problemen zu kämpfen hat, welche die Entwickler beschäftigen. Wenn die Anwendung in einem so schlechten Zustand ist, passt in vielen Fällen auch das Umfeld nicht: Anforderungen sind schlecht, Prozesse nicht gut, Supportprozesse verbesserungswürdig.Der Punkt, an dem man ansetzen sollte, liegt aber nicht selten außerhalb der Entwickler: Durch bessere Anforderungen haben Entwickler mehr Zeit für die Entwicklung. Ein besserer Prozess lässt Entwickler schneller arbeiten. Je mehr Fehler erst gar nicht bei den Entwicklern landen, desto mehr Zeit haben diese für die Entwicklung. Ich versuche zu Beginn eines solchen Projekts erst immer das Umfeld zu analysieren und zu optimieren, damit die Entwickler nicht mehr „jeden Mist“ machen müssen, sondern sich ganz auf ihre Kernaufgabe konzentrieren können. Dabei passiert es nicht selten, dass die Arbeitsleistung des gesamten Teams um 20 bis 30 Prozent gesteigert werden kann. Diese Leistungssteigerung kann dann für das anstehende Refactoring genutzt werden, ohne dass die Entwicklungsgeschwindigkeit neuer Funktionalitäten grundlegend beeinträchtigt wird.Fazit
„Aber xyz wird schwer“, „Aber wie Refactoring, wenn die Funktion gleichzeitig verändert wird“, „Aber wir haben X Branches, da geht es nicht“ – glauben Sie mir, solche Refactorings sind immer schwierig, sehr individuell und es gibt 1000 Gründe, es nicht zu machen. Und doch führt kein Weg daran vorbei. Die Suppe haben Sie sich selbst eingebrockt, oft über viele Jahre, und nun müssen Sie diese Löffel für Löffel runterwürgen. Mit der richtigen Einstellung, einer guten Analyse und der richtigen Strategie ist es aber zu schaffen. Mein Beitrag dazu war diese Artikelserie zu Schulden in der Softwareentwicklung, die hiermit ihr Ende findet.Ich wünsche Ihnen viel Erfolg!Fussnoten
- David Tielke, Die Schuld, dotnetpro 4-5/2025, Seite 86 f., http://www.dotnetpro.de/A2504-05DDD