Agile Softwareentwicklung, Project management, Software Development

Hindernisse wegsprengen – technische und organisatorische Schulden (er)kennen

Wenn die Lieferung von Software ins Stocken gerät, dann wird dieser Umstand meist durch technische Schulden gerechtfertigt. Diese zu bewerten, einzuplanen und abzuarbeiten, ist die Aufgabe des gesamten Teams. Leider sind diese Probleme nicht immer rein technischer Natur. Dieser Artikel gibt einen Überblick über einige technische und organisatorische Schulden, die den Entwicklungsalltag so richtig vermiesen können.

Irgendwann, irgendwo in Deutschland: Das Team, bestehend aus Entwicklern, Scrum-Master und Product-Owner (PO) sitzt im Sprint-Planning zusammen. Die letzten Sprints liefen wie am Schnürchen. Das Team ist motiviert und macht sich gerade an die Abschätzung der Topstories im Backlog für die Weiterentwicklung am Webshop.

Oliver (PO): „… so, diese Story ist so ähnlich wie die Story im vorletzten Sprint für die Eingabemaske von Adressdaten. Wir wollen diesmal dem Kunden die Möglichkeit bieten, eine zusätzliche Lieferadresse zu speichern und diese im Bestellprozess auch auszuwählen.“

Dirk (Entwickler):Wir haben im Team schon darüber gesprochen und würden diese Story mit fünf Story-Points bewerten.“

Oliver (PO): Warum denn so viel? Bei der anderen Story habt ihr doch nur drei geschätzt und sicher umgesetzt. Außerdem haben wir bereits ein Formular, das wir sicherlich wiederverwenden können.“

Ingo (Entwickler): Wir haben an der Komponente mit dem bisherigen Formular noch ein paar offene Baustellen, weil der Sprint sehr voll war. Außerdem ist Alex im nächsten Sprint im Urlaub, und er hatte hauptsächlich daran gearbeitet.“

Julia (Scrum-Master): Oliver, ich glaube, was das Team dir sagen will, ist, dass wir technische Schulden haben und diese gerne im Zuge der Story mit abarbeiten möchten. Ist das für dich in Ordnung?“

Oliver (PO): Prinzipiell schon, aber ich verstehe nicht, warum Alex Urlaub jetzt eine technische Schuld sein soll.“

Kommt Dir diese Situation vertraut vor? Diskussionen über Story-Points oder Rechtfertigungen für unfertige Stories. Nicht selten werden solche Probleme mit technischen Schulden begründet. Aber was sind technische Schulden überhaupt?

debtsAls Ward Cunningham 1992 den Begriff definierte, war die Motivation klar. Technische Schuld ist eine Metapher, um ein allgemeines Verständnis zu bekommen, warum die Entwicklung eines Systems langsamer wird, wenn bestimmte Aktivitäten beim Programmieren bewusst vernachlässigt werden.

Shipping first-time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite … The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation … [1]

Die ursprüngliche Definition besagt, dass es eine bewusste Entscheidung ist, technische Schulden aufzunehmen, um kurzfristig eine höhere Entwicklungsgeschwindigkeit zu erhalten. Baut man diese Schulden zukünftig nicht ab, zahlt man Zinsen auf diese Schulden, was wiederum in einer langsameren Entwicklungsgeschwindigkeit resultiert.

Zusätzlich zur ursprünglichen Definition hat Martin Fowler 2003 mit dem Technical Debt Quadrant eine Taxonomie vorgegeben, die als Hilfe zur Einordnung von technischen Schulden dient. Neben den bis dato bekannten Problemen die bewusst in Kauf genommen werden, führte Fowler auch unbewusste Versäumnisse als technische Schulden an.

Darüber hinaus wird eine Einteilung in sorglos und umsichtig angehäufte Schulden vorgenommen. Diese Taxonomie kann als Hilfe dienen, um bestehende Probleme bei der Entwicklung zu bewerten. [2]

tech_debt_quadrant-2

Doch was ist mit unserem Beispiel vom Anfang?

  • Warum werden wir langsamer, wenn ein bestimmter Entwickler fehlt?
  • Was passiert, wenn wir keine Tests haben?
  • Und wenn wir den Code nicht dokumentieren?
  • Sind die Anforderungen zu technisch oder doch eher zu ungenau?
  • Hatten wir für dieses Problem nicht bereits Hilfsklassen?

Einige dieser Fragen lassen sich tatsächlich auf technische Schulden zurückführen, andere sind eher nicht im Code zu finden. Greift man den Grundgedanken der technischen Schulden auf – also alles, was bewusst oder unbewusst in Kauf genommen wird und die Softwareentwicklung verlangsamt, – kann man die Metapher auf andere Bereiche der Softwareentwicklung übertragen.

Eine andere Kategorie, die im Rahmen von Agilität und Selbstorganisation besonders präsent wird, sind die organisatorischen Schulden. Diese Art der Schulden ergeben sich eher aus Missständen in Prozessen, Anforderungen oder einfach aus dem Miteinander von Menschen.

Organizational Debt: The interest companies pay when their structure and policies stay fixed and/or accumulate as the world changes. [3]

Im Folgenden zeigen wir verschiedene Arten von Schulden und werden diese den technischen bzw. organisatorischen Schulden zuordnen.

Arten von technischen Schulden

  1. Implementation-Debt
    Implementierungsschulden finden sich als Code-Smells im Code wieder. Dies geschieht häufig durch die Verletzung von gängigen Code-Praktiken (DRY, KISS etc.). Als Resultat wird der Code schwerer lesbar und die Wartbarkeit sinkt. [5]

    Mögliche Indikatoren: duplizierter Code, Switches-in-Loops, Verletzung von Coding-Guidelines 

  2. Design-Debt
    Diese Art von Schulden bezieht sich auf das Verletzen von Designprinzipien. Im Bereich der objektorientierten Programmierung sind die SOLID-Prinzipien prominent. Starke Verschachtelungen, Verletzung von Zuständigkeiten, zyklische Abhängigkeiten – all diese Probleme führen dazu, dass man auf den Big Ball of Mud zusteuert.
    Was zu Beginn eines Softwareprojektes kaum relevant ist, wird bei wachsender Anzahl an Klassen schnell zu einem Problem. [5,6]

    Mögliche Indikatoren: große Klassen (God classes), übermäßiger Einsatz von Singletons, zyklische Abhängigkeiten, erhöhter Aufwand beim Testen

  3. Architecture-Debt
    Im Bereich der Architektur führt falsches Schneiden von Modulen, Schichten und Fachlichkeiten ebenso zu einem schlechtem Verständnis des Systems. Ist zudem noch der Architekturstil, die Programmiersprache, das Framework etc. falsch ausgewählt, wird es schwer, die Qualitätsanforderungen an das System zu erfüllen. [5,6,7]

    Mögliche Indikatoren: keine expliziten Qualitätsanforderungen, Mischung von technischen und fachlichen Klassen, hohe Kopplung zwischen Schichten

  4. Test-Debt 
    Ein Klassiker der technischen Schulden: Testschulden. Um schnell zu liefern, werden häufig Tests ausgelassen – mit dem Versprechen, diese nachzuliefern. Was kurzfristig funktioniert, fällt häufig zu Lasten der Entwicklung, sobald der bestehende Code angepasst werden muss. Folgt man der Definition von Michael Feathers, hat man mit fehlenden Tests sofort Legacy Code erzeugt. [5,6]

    Mögliche Indikatoren: hohe Fehlerquote bei Änderungen am bestehenden Code, geringe Testabdeckung, langsame Tests 

  5. Documentation-Debt
    Dokumentationsschulden sind vielleicht nicht so offensichtlich, jedoch existieren sie auf verschiedenen Stufen. Dieses Problem tritt auf, wenn
    die Dokumentation fehlt, unvollständig oder schlicht veraltet ist. Somit ist es für neue Entwickler im Team schwieriger, sich in die Codebasis einzuarbeiten. Im Code sind Klassen und Methoden gar nicht oder nur spärlich kommentiert. Die Art der Kommentare beschreibt nur, was der Code tut und nicht warum. [5,6]

    Mögliche Indikatoren: langes Onboarding neuer Mitarbeiter, mehrfache Implementierungen von Hilfsmodulen, fehlende Coding-Guidelines, fehlendes Verständnis für getroffene Design- und Architekturentscheidungen

  6. Build-Debt
    Kein Buildmanagement, keine Buildautomatisierung? Was heutzutage mit Prinzipien aus dem DevOps-Bereich, wie Continuous-Integration, Continuous-Deployment und Continuous-Delivery, gelöst wird, sollte ebenfalls in Betracht gezogen werden. Langes Warten auf Rückmeldungen durch die Integration oder gar von Anwendern führt dazu, dass Änderungen zwischen Releases womöglich nicht den Anforderungen entsprechen. Ein weiteres Problem ist das Fehlen von Testautomatisierung, um ungewollte Änderungen im System schnellstmöglich aufzudecken.
    Kurz: Schnelle Feedbackzyklen sind wichtig! [6]

    Mögliche Indikatoren: „Buildsystem? Was ist das?“, lange Buildzeiten, ungenutzte Flags/Profile in Buildskripten, unnötige Targets
Tech Debt by monkeyuser.com

Arten von organisatorischen Schulden

Während technische Schulden ein Softwareprojekt verlangsamen können, sobald die erste Codezeile niedergeschrieben ist, können organisatorische Schulden den ganzen Entwicklungsprozess schon vor dem Startschuss negativ beeinflussen.

  1. Process-Debt
    „Scrum klappt bei uns nicht!“, „Wir machen lieber Wasserfall!“ oder „Das Projekt war schon von Anfang an zum Scheitern verurteilt!“. Ein Prozess sollte zur Organisation passen. Häufig treten diese Probleme auf, wenn neue Prozesse eingeführt werden. Jedoch muss man in diesem Fall wiederholt reflektieren, ob das Vorgehen zur Organisation und deren Zielen passt.

    Mögliche Indikatoren: unklare Vision, Vermischung von Rollen (beispielsweise Scrum-Master, Product-Owner), häufige Störungen von außen, Meetings ohne Ergebnisse
  2. Requirement-Debt
    Das Umsetzen von Anforderungen entspricht dem täglichen Brot des Entwicklers. Erfüllt das Ergebnis nicht die Wünsche des Kunden, dann müssen Anforderungen und Implementierung überarbeitet werden. Zudem ist zusätzlicher Aufwand für Abstimmungen einzuplanen, um die ursprünglichen Anforderungen zu konkretisieren bzw. zu korrigieren. [6]

    Mögliche Indikatoren: ungenaue bzw. falsche Anforderungen, ungepflegtes Backlog, häufiges Umpriorisieren von Features, hoher Rücklauf von abgeschlossenen Features

  3. Infrastructure-Debt
    Wenn die Werkzeuge, die Entwickler tagtäglich nutzen, für die Entwicklungstätigkeit nicht angemessen sind, dann schlägt diese Schuld zu. Hierzu zählen die Hardware, die Software, die Zugangsmöglichkeiten zu anderen Systemen und die Aspekte der Beschaffung dieser Arbeitsmaterialien. [6]

    Mögliche Indikatoren: fluchende Mitarbeiter, fehlende oder veraltete Arbeitsgeräte, lange Wartezeiten für Zugänge, häufige Ausfälle von Servern und Diensten, umständliche Bestellprozesse
  4. “Don't believe Conway”-Debt
    Das Gesetz von Conway besagt, dass Organisationen, die Systeme entwerfen, die Struktur dieser Systeme in der Organisation abbilden. Anders betrachtet, kann ein System auch entsprechend der Struktur der Organisation entworfen werden. Beachtet man dies nicht, wenn also Struktur des Systems und die Struktur der Organisation nicht zusammenpassen, dann kämpft man unentwegt gegen dieses Gesetz an.

    Mögliche Indikatoren: viele Meetings für Abstimmungen, hohe Wartezeiten bzw. häufige Blocker durch andere Abteilungen

  5. People-Debt
    Wenn Menschen zusammenkommen, dann kommen auch verschiedene Geschichten, Kulturen, Ansichten und Emotionen zusammen. Funktionale Teams bekommt man nicht geschenkt, und Konflikte sind normal. Es sollte das Ziel sein, diese Konflikte in etwas Positives zu verwandeln und damit weiter erfolgreich zu sein, denn es menschelt hier wie überall. Ist es nicht möglich Konflikte zu beseitigen, so hat man es mit dieser Art von Schulden zu tun. [6]

    Mögliche Indikatoren: gestörte Kommunikation, Anfeindungen, „problematische“ Arbeitshaltung („Dienst nach Vorschrift“), Fehlzeiten, Fluktuation, Fernbleiben von Meetings, Cliquenbildung

Fazit

team_success

In der Softwareentwicklung sind Schulden nicht nur für technische Aspekte eine sinnvolle Metapher. Es gibt viele Faktoren, die den Erfolg der Softwareentwicklung beeinflussen. In Zeiten neuer Technologien und stark verteilter, komplexer Systeme, an denen teils mehrere Teams mit unterschiedlichem Hintergrund arbeiten, gibt es auch neue Herausforderungen.

Im Grunde sind alle oben genannten Probleme, also die technischen und organisatorischen Schulden, auf die beteiligten Personen zurückzuführen. Daher kann man diese Herausforderungen nur als Team bewältigen. Nur gemeinsam kann man die Hindernisse wegsprengen und auch weiterhin erfolgreich Software liefern.

Quellen

[1] Ward explains Debt Metapher, W. Cunningham, http://wiki.c2.com/?WardExplainsDebtMetaphor

[2] Technical Debt Quadrant, M. Fowler, https://martinfowler.com/bliki/TechnicalDebtQuadrant.html

[3] Introduction to the Technical Debt Concept, J. Letouzey and D. Whelan, https://www.agilealliance.org/wp-content/uploads/2016/05/IntroductiontotheTechnicalDebtConcept-V-02.pdf

[4] How To Eliminate Organizational Debt, A. Dignan, https://medium.com/the-ready/how-to-eliminate-organizational-debt-8a949c06b61b

[5] Langlebige Software-Architekturen: Technische Schulden analysieren, begrenzen und abbauen, C. Lilienthal, ISBN: 9783864902925

[6] Technical debt: From metaphor to theory and practice, P. Kruchten, R. L. Nord and I. Ozkaya, IEEE software, 29(6):18–21, 2012

[7] An exploration of technical debt, E. Tom, A. Aurum and R. Vidgen, Journal of Systems and Software, 86(6):1498–1516, 2013

   
Über Martin Schmidt

Martin Schmidt arbeitet als IT-Berater mit den Schwerpunkten Softwarearchitektur und Agilität am Standort Berlin der itemis AG. Er ist vor allem an der Lösung von menschlichen und technischen Problemen rund um Legacy-Systeme interessiert. - „People first, tech second.“