Technische Schulden – mögliche Folgen von sparsamer Software-Entwicklung

Ein Entwicklerteam, das bei der Software-Entwicklung oder beim Aufbau einer IT-Infrastruktur kostengünstig und schnell vorgeht, erkauft sich diese Ersparnis durch technische Schulden. Technische Schulden bezeichnen die Folgen, die absichtliche oder unabsichtliche Nachlässigkeiten, Fehler und Schwächen im Code nach sich ziehen. Spätere Korrekturen und Wartungen bremsen die Produktivität und sorgen für kostspieligen Mehraufwand. Worauf müssen Sie achten, wenn Sie technische Schulden bei der Software-Entwicklung vermeiden wollen?

Warum spricht man von technischen Schulden?

1992 führte der Programmierer und Mitautor des Manifests für agile Software-Entwicklung Ward Cunningham die Metapher der technischen Schulden ein. Cunningham wollte mit seinem Sinnbild verdeutlichen, wie wichtig Refactoring, also die regelmäßige Korrektur am Code, für eine Software ist. Nur so lässt sich vermeiden, dass sich eine Software durch anwachsende Funktionsmängel und Strukturschwächen immer mehr verschuldet.

Der Begriff Schulden impliziert auch Zinsen, denn technische Schulden sind für auftraggebende Unternehmen vor allem aus finanzieller Sicht bedeutsam. Nicht nur ziehen technische Schulden mehr Aufwand und verminderte Produktivität durch nachträgliche Wartungen nach sich, sondern auch mehr Kosten. Je mehr eine Teamleitung die Wartung einer mangelhaften IT-Infrastruktur oder Anwendung vernachlässigt, umso mehr Zinsen erzeugen die Schulden und umso teurer sind die Code-Korrekturen.

Definition: Technische Schulden

Technische Schulden bezeichnen bewusste oder versehentliche Fehler, Mängel und Schwächen im Code, die durch mangelnde Kommunikation, Teamleitung, Qualifikation oder übereilte Veröffentlichung von Produkten entstehen und bei ausbleibendem Refactoring konstant anwachsen.

Der Technische-Schulden-Quadrant: Vier Typen von Schulden

Nach Ward Cunningham entstehen technische Schulden durch Nachlässigkeiten im Code, die aus Zeit- oder Budgetgründen zu einer schnelleren, jedoch fehlerhaften Problemlösung führen. Ein gründlicher, lückenloser Code ist aufwendig und langwierig. Daher entscheiden sich Entwickler unter Umständen für einen unsauberen Code, um Zeit und Aufwand zu sparen. Diese Ersparnis erkaufen sie sich durch Schulden.

Für Cunningham ist dieser ökonomische Aspekt des Programmierens nicht ungewöhnlich oder unnatürlich. Werden technischen Schulden aber nicht durch Refactoring ausgeglichen und der Code nicht regelmäßig optimiert, kommt die Entwicklung durch metaphorische Zinsen ins Stocken oder zum Stillstand.

Martin Fowler, Autor von Refactoring: Improving the Design of Existing Code, konkretisierte Cunninghams Metapher und unterteilte technische Schulden in vier Typen, die er im Technische-Schulden-Quadranten veranschaulichte:

Rücksichtslose Schulden

Umsichtige Schulden

Bewusste Schulden

  • Zeit-/Budgetmangel
  • Vernachlässigtes Refactoring
  • Priorisierung von schneller Lieferung der Software und Verpflichtung zum Refactoring

Versehentliche Schulden

  • Mangelnde Qualifikationen
  • Ungenügende Dokumentation
  • Overengineering
  • Anti-Patterns
  • Code-Erosion
  • Konstantes Refactoring behebt historisch gewachsene Programmierfehler und -mängel und hilft, aus Fehlern zu lernen

Technische Schulden nach Cunningham und Fowler können somit sowohl bewusst als auch versehentlich entstehen. Da Technologie und Programmierung kontinuierliche Revisionen und Verbesserungen erhalten, lassen sich Code-Smell und Code-Erosion kaum vermeiden. Auch Software altert und baut ohne Updates und Refactoring Schulden auf. In den meisten Fällen sind technische Schulden jedoch durch ökonomische Entscheidungen oder absichtliche bzw. unabsichtliche Programmierfehler zu erklären.

Welche Ursachen haben technische Schulden?

Technische Schulden haben meist ähnliche Auswirkungen auf die Software-Entwicklung, ihre Ursachen können jedoch sehr unterschiedlich sein.

  • Mangelndes Qualitätsmanagement: Projekte laufen ohne qualitätssichernde Kontroll-, Mess- und Testmechanismen und bauen fortlaufende Schulden auf.
     
  • Ökonomischer Druck: Ökonomische Faktoren und eine schnelle Entwicklung werden auf Drängen von Auftraggebern hin oder aufgrund von Konkurrenzdruck priorisiert und ein sauberer Code vernachlässigt.
     
  • Mangelnde Qualifikation: Das fachliche Wissen des Entwicklerteams entspricht nicht den Anforderungen eines eleganten und sauberen Codes. Die Folge ist Code-Smell oder Spaghetti-Code.
     
  • Ungenügende Dokumentation/Kommunikation: Der Entwicklungsprozess verläuft ohne parallele Dokumentation der Codeerweiterungen und -änderungen. Zudem werden Änderungen im Code nicht für spätere Programmierer erfasst und kommuniziert. Die Möglichkeiten für Refactoring sind begrenzt oder nicht vorhanden.
     
  • Aufgeschobenes Refactoring: Bewusst in Kauf genommene technische Schulden werden nicht zeitnah behoben, weil Refactoring vernachlässigt oder aufgeschoben wird.
     
  • Parallele Anwendungsentwicklung: Parallele Entwicklungsschritte, die zusammengeführt und nicht aufeinander abgestimmt werden, führen zur Anhäufung von Schulden.
     
  • Zu komplexer Code: Code-Abschnitte sind zu kompliziert und unlogisch. Kleine Änderungen können zu weiteren Fehlern führen und Schulden vermehren. Im schlimmsten Fall entsteht auch hier Spaghetti-Code.
     
  • Unstrukturierte Entwicklungsabläufe: Die Anwendungsentwicklung beginnt, bevor ein konkretes Design oder konkrete Abläufe definiert und beschlossen wurden.
     
  • Code-Outsourcing: Entwicklungsschritte werden ausgelagert und führen beim späteren Zusammenfügen der Abschnitte zu Fehlern im Code, die von der Teamleitung in Kauf genommen oder übersehen werden.
     
  • Kurzfristige Änderungen im Ablauf: Kurzfristige Änderungen im Code werden aufgrund von Zeitdruck nicht getestet.

Technische Schulden und agile Software-Entwicklung

Ward Cunningham definierte nicht nur die Metapher der technischen Schulden, sondern ist auch Mitautor und Erstunterzeichner des Manifests für agile Software-Entwicklung. Diese Philosophie in der Software-Entwicklung will durch Leitsätze und Prinzipien eine produktivere und flexiblere Anwendungsentwicklung und Veröffentlichung fördern.

Statt über lange Zeiträume an große Projekte gebunden zu sein, sollen sich kleinere und unabhängigere Teams um kürzere Arbeitsphasen und schnellere Veröffentlichungen von kleineren Projekten wie Anwendungen, Programmteilen und Updates bemühen.

Agile Software-Entwicklung hat zur Folge, dass Teams in kleinen Schritten Code schreiben und ändern und Arbeitsschritte schneller zum Abschluss kommen. Durch den Fokus auf Schnelligkeit und Produktivität erhöht sich die Gefahr, unsauberen Code und damit technische Schulden anzuhäufen. Vor allem wenn agile Software-Entwicklung nicht mit Refactoring Hand in Hand geht, wachsen Schulden unweigerlich an.

Welche Auswirkungen haben technische Schulden auf Software-Entwicklung?

Die Auswirkungen von technischen Schulden entsprechen den Folgen von Krediten im Finanzwesen. Werden die Schulden nicht rechtzeitig und regelmäßig abgebaut, entstehen Zinsen, die sich in gebremster Entwicklung, sinkender Produktivität und höherem Kostenaufwand zeigen.

Es ist daher im Interesse von Auftraggebern, die Entwicklung langfristig durch umfassendes Qualitätsmanagement zu begleiten und zu überwachen, um die schnellere und kostensparende Fertigstellung und Veröffentlichung von Produkten nicht mit späteren, kostspieligen Fehlerkorrekturen oder einem Stillstand der Entwicklung zu bezahlen.

Wie lassen sich technische Schulden vermeiden?

Technische Schulden lassen sich aufgrund neuer Technologien und sich ändernder Ansätze in der Software-Entwicklung nicht gänzlich ausschließen. Um Programme und Anwendungen regelmäßig und schnell zu veröffentlichen und Teams nicht langfristig an Projekte zu binden, werden sie sogar in Kauf genommen. Es gibt jedoch vorbeugende Maßnahmen, um das Entstehen oder Anwachsen von Schulden zu vermeiden oder zu reduzieren:

  • Standardisierte Abläufe für Refactoring und Qualitätsmanagement
  • Stetig aktuelle Tools zur Fehlermessung und -analyse
  • Fachliches Wissen durch Fortbildungen dem Stand der IT anpassen bzw. die Teamzusammensetzung nach Qualifikation festlegen
  • Codes durch Unterteilung in Klassen und verständliche Methoden übersichtlich gestalten und für neu hinzukommende oder außenstehende Programmierer lesbar schreiben
  • Klare Zuständigkeiten und Aufgabenverteilungen in Teams, um Doppelungen, Redundanzen und kontraproduktive Arbeitsschritte zu vermeiden
  • IT-Architektur durch stetige Überwachung, Messung und Qualitätssicherung auf aktuellem Stand halten