zurück zum Artikel

Qualitätsinvestitionen statt technischer Schulden

Felix Müller, Eberhard Wolff

Wohl jeder Entwickler kennt die Probleme bei der Wartung und Änderung alter Codebasen. Der Code ist schlecht strukturiert, es gibt nur wenige Tests, und die Versionen der verwendeten Bibliotheken sind recht alt. Diese technischen Probleme dem Management besser zu kommunizieren, ist die Metapher der "technischen Schulden" angetreten.

Qualitätsinvestitionen statt technischer Schulden

Wohl jeder Entwickler kennt die Probleme bei der Wartung und Änderung alter Codebasen. Der Code ist schlecht strukturiert, es gibt nur wenige Tests, und die Versionen der verwendeten Bibliotheken sind recht alt. Viele Dinge sind außerdem viel zu kompliziert umgesetzt. Diese technischen Probleme dem Management besser zu kommunizieren, ist die Metapher der "technischen Schulden" angetreten.

Die Idee hinter der Metapher "technische Schulden" ist, den Qualitätskompromiss als Schuld zu begreifen. Er lässt sich sogar beziffern: Es sind der Aufwand beziehungsweise die Kosten zum "Reparieren" der Codebasis – also zum Verbessern der Struktur, zum Schreiben der entsprechenden Tests oder zur Umstellung auf neue Versionen der verwendeten Libraries.

Bei einem Qualitätskompromiss steigt die Produktivität kurzfristig - langfristig sinkt sie jedoch (Abb 1).

Bei einem Qualitätskompromiss steigt die Produktivität kurzfristig - langfristig sinkt sie jedoch (Abb 1).

Auf Schulden sind auch Zinsen zu zahlen. Bei der Metapher der technischen Schulden sind die Zinsen die verringerte Produktivität des Teams bei der Implementierung neuer Features. Die erste Intuition bei technischen Schulden ist es, sie abzutragen und zu verringern. Das ist aber nicht immer sinnvoll. Im Gegenteil: Zusätzliche technische Schulden können eingegangen werden, um ein neues Features "quick & dirty" zu implementieren. In dem Fall opfert das Team die Qualität für einen Vorteil bei der Time-to-Market. Langfristig verkehrt sich der Produktivitätsvorteil dann aufgrund der "Zinsen" in einen Nachteil, sodass man vorsichtig mit dem Aufnehmen von Schulden sein muss (Abb. 1).

Für das Abtragen der Schulden gibt es unterschiedliche Ansätze. Kleinere Verbesserungen sollte jeder Entwickler in seiner täglichen Arbeit durchführen. Stehen aber größere Änderungen an, ist der Aufwand einzuplanen und irgendwie im Budget vorzusehen. Dazu gibt es viele unterschiedliche Ansätze – ein InfoQ-Artikel [1] führt einige aus. Bei der Diskussion um ein solches Budget soll gerade die Metapher der technischen Schulden helfen. Schließlich stammt sie aus der Finanzwelt, einem Bereich, mit dem Manager vertraut sein sollten.

Das Team kann nun eine Aussage treffen und gegebenenfalls den Aufwand für das Abtragen der Schulden abschätzen. Werkzeuge wie SonarQube können dabei helfen. Oft ist der Aufwand für das "Aufräumen" der Codebasis recht hoch (Abb. 2).

Beispielhafte Ausgabe des SonarQube Technical Debt Plugin: Der Aufwand zum Aufräumen ist hoch, und auch ist es fraglich, wie wichtig das Beseitigen der Code-Duplikationen wirklich ist (Abb. 2).

Beispielhafte Ausgabe des SonarQube Technical Debt Plugin: Der Aufwand zum Aufräumen ist hoch, und auch ist es fraglich, wie wichtig das Beseitigen der Code-Duplikationen wirklich ist (Abb. 2).

Beim verantwortlichen Management kann dieser Ansatz zu Schwierigkeiten führen. Immerhin sind mit dem Projekt offensichtlich versteckte Aufwände und ein technisches Risiko verbunden. Woher soll das Budget für diese Aufwendungen kommen? Vom Kunden? Aber es sind ja keine Features. Am Ende bekommen die Entwickler oft kein "Go" für umfangreiche Verbesserung. In der Situation treffen sie die Entscheidung zum Umgang mit den technischen Schulden selbst.

Das ist teilweise professionell – immerhin ist ein Fokus auf Qualität ein Zeichen professioneller Arbeitsauffassung –, aber wenn ganze Tage in Verbesserungen investiert werden müssten, sollte es eine Managemententscheidung sein. Der Aufwand ist gegen die Implementierung von Features und Time-to-Market zu priorisieren. Das sollte nicht unter dem "Management-Radar" geschehen, außer wenn die Entwickler den Aufwand in den Aufwand zur Implementierung der Stories "einpreisen" – also bei jedem Feature überlegen, ob der Code vorher verbessert werden sollte, um dann das Feature einfacher zu implementieren. Auf jeden Fall verdeutlicht das, dass die Metapher der technischen Schulden nicht unbedingt hilft, um dem Management die Qualitätsprobleme zu veranschaulichen und sinnvolle Entscheidungen vorzubereiten.

Die Qualität des Codes hat nämlich eine entscheidende Eigenschaft: Sie ist völlig egal – solange der Code nicht geändert werden soll. Dann aber ist die Qualität äußerst wichtig. Das Hauptproblem ist also: Welche Schulden sind egal und welche extrem wichtig? Welche Schulden sollen wann abgetragen werden? An dieser Stelle hilft die Metapher der technischen Schulden allein nicht weiter.

Die technischen Schulden haben mit dem erfolgreichen Abschluss eines Projekts nichts zu tun. Aber am Ende entstehen in einigen Situationen ökonomisch unsinnige Entscheidungen. Wenn die Qualität langfristig vernachlässigt wird, sinkt die Produktivität immer weiter – was insbesondere Manager nicht sinnvoll finden
können. Entwickler können solche Situationen vorhersehen und haben dann oft ein schlechtes Gefühl, aber sie können es nicht belegen oder gegenüber dem Management klar kommunizieren.

Dazu lässt sich ein anderer Begriff aus der Finanzwelt nutzen: die Investition. Wenn Entwickler die Qualität des Codes erhöhen, ist das eine Investition. Sie ist nur sinnvoll, wenn sich so in Zukunft eine höhere Produktivität erreichen lässt. Qualität ist eben kein Selbstzweck, sondern erleichtert Änderungen an der Codebasis, beeinflusst so die Produktivität und ist daher von ökonomischer Bedeutung. Also ist die grundlegende Idee, dass Qualitätsverbesserungen eine Investition sind. Sie sind sinnvoll, wenn durch die Verbesserungen mehr Aufwand eingespart wird, als für die Umsetzung der Verbesserungen notwendig ist. Ideal wäre es, wenn sich sogar ein Return on Investment für die Qualitätsmaßnahmen berechnen ließe.

Die Metapher der Qualitätsinvestition denkt die technischen Schulden weiter. Dies sind die Kosten, die zur Behebung von Qualitätsmängeln aufzubringen sind. Die Qualitätsinvestition ermöglicht es, aus diesen Kosten einen Nutzen abzuschätzen, was letztlich in einem Gewinn resultiert.

Die SQALE-Methode [2] (Software Quality Assessment based on Lifecycle Expectations), ein Qualitätsmodell, formuliert zwei Kostenarten: Sanierungskosten (RC, engl. remediation cost) und Nichtsanierungskosten (NRC, engl. non-remediation costs). Erstere fallen an, wenn ein Qualitätsmangel behoben wird. Sie sind mit den technischen Schulden gleichzusetzen. Im Gegensatz dazu treten die Nichtsanierungskosten auf, wenn ein Qualitätsmangel nicht behoben wird – man also mit der schlechten Qualität weiterarbeitet. Bisherige Implementierungen wie das SQALE-Plug-in von SonarQube nutzen lediglich die Sanierungskosten. Dabei liegt der Schlüssel für einen ökonomisch sinnvollen Umgang mit der Qualität in beiden Kostenarten.

Räumt man den Code auf und behebt die Qualitätsmängel, werden die Sanierungskosten fällig. Allerdings spart sich das Team dann die Nichtsanierungskosten. Demnach lohnt es sich, nur dort die Qualität zu verbessern, wo die Nichtsanierungs- größer als die Sanierungskosten sind. Denn dann ergibt die Investition in die Qualität einen Gewinn. Das lässt sich mit dieser Formel einfach beschreiben:

Gewinn = NRC – RC

Immer wenn das Beheben eines Qualitätsmangels günstiger ist, als mit ihm zu leben, lohnt sich eine Investition in die Qualität. Wie erwähnt, gewinnt die Qualität erst an Bedeutung, wenn der Code geändert wird. Das heißt für die gezeigte Gewinnrechnung, dass die Nichtsanierungskosten nur auftreten, wenn der Code in Zukunft angefasst wird. Denn nur dann wird das Team durch die schlechtere Qualität langsamer. Also ist für die Investitionsbetrachtung neben den beiden Kostenarten zusätzlich die Änderungswahrscheinlichkeit des betrachteten Codes zu schätzen. Daher lässt sich die Metapher der Qualitätsinvestition mit drei Schätzungen umsetzen. Ein Beispiel mag das verdeutlichen.

Ein fiktives System besteht aus drei Komponenten – beispielsweise für die Verwaltung von Kunden, von Bestellungen und des Lagers. Die Kundenverwaltung ist sehr alt und wird nicht mehr weiterentwickelt. Für eine Qualitätsinvestition ist diese Komponente also mit einem Verlust behaftet, da die Nichtsanierungskosten mit einer Wahrscheinlichkeit von 0 Prozent eintreten.

Bei den Komponenten für Lager und Bestellungen sieht das jedoch anders aus. Es ist bekannt, dass in der nächsten Iteration umfangreiche Änderungen an dem Bestellprozess vorgenommen werden. Ebenso ist aufgrund der Erfahrung mit der Weiterentwicklung des Systems bekannt, dass Änderungen an dem Bestellsystem mit einer geringen Wahrscheinlichkeit Änderungen am Lagersystem bewirken. Daher ist für das Bestellsystem anzunehmen, dass größere Teile des Codes geändert werden, während beim Lagersystem zwar auch Änderungen vorgenommen werden, aber nicht im gleichen Umfang. Solche groben Schätzungen sind meistens ausreichend, und es ist auch einfacher, sich auf einen solchen Wert zu einigen. Die Erfahrung lehrt, dass feingranularere Schätzungen meist nur eine Präzision vortäuschen.

In einem weiteren Schritt sind die Qualitätsmängel in diesen beiden Komponenten zu schätzen. Da wäre zum Beispiel die unterirdische Testabdeckung im Bestell- oder die enge Kopplung von Klassen im Lagersystem. Für alle auffallenden Punkte werden jeweils Sanierungs- und Nichtsanierungskosten geschätzt. Letztlich ergeben sich die Nichtsanierungskosten als die Differenz zwischen einer Schätzung des Implementierungsaufwands mit und ohne die betrachtete Qualitätsinvestition. Dabei gilt es, die Änderungswahrscheinlichkeit in die Betrachtung mit einzubeziehen. Die Nichtsanierungskosten sind im Bestellsystem nicht nur besonders hoch, weil die Qualität dort so schlecht ist, sondern auch, weil umfangreiche Änderungen vorzunehmen sind:

Es ergibt sich also für das Bestellsystem ein Gewinn von zwei Tagen (= 5d-3d), während beim Lagersystem kein Gewinn zu erwarten ist. Damit ist klar, dass derzeit eine Investition ins Bestellsystem sinnvoll ist, da das Verbessern der Testabdeckung nach Schätzungen des Teams einen Gewinn verspricht. Gleichzeitig ist die Investition in das Lagersystem ökonomisch nicht sinnvoll – wenn aber für die nächsten Iterationen auch Änderungen in dieser Komponente absehbar sind, könnte es dennoch sinnvoll sein, die Qualität hier zu verbessern. In so einem Fall kann der Planungshorizont für die Qualitätsinvestitionen größer sein als der für die Features, was die Abwägungen erschwert.

Ist der Gewinn ermittelt, lässt sich daraus der Return on Investment berechnen, eine Kenngröße aus der Finanzwelt, die angibt, wie viel Gewinn im Verhältnis zum Mitteleinsatz erwirtschaftet wird. Dafür ist der Gewinn durch die Sanierungskosten zu dividieren. Für die Qualitätsinvestition im Bestellsystem bei diesem Beispiel ist das ein ROI von rund 67 Prozent (=2d/3d). Mit dieser Zahl kann man dem Manager den Nutzen einer Investition in die Qualität vor Augen führen.

Die Metapher der Qualitätsinvestition ermöglicht eine andere Art der Diskussion mit dem Management. Statt eines Kostenwerts für die technischen Schulden lässt sich dem Manager mitteilen, dass das Aufräumen einer Komponente absehbar Zeit und Aufwand einspart. Für den Manager bedeutet das eine Win-Win-Situation: Budget wird eingespart, und die Entwickler sind zufrieden, da sie die Codequalität verbessern können. Ebenso kann der Manager abwägen, ob die Investition sinnvoll ist oder beispielsweise eine "Quick & Dirty"-Entwicklung ausreicht oder vielleicht sogar wegen des Time-to-Markets notwendig ist.

Letztlich ist die Qualitätsinvestition eine Abwägung unterschiedlicher Schätzungen, was ökonomisch am sinnvollsten ist. Es stellt sich jedoch die Frage, warum die Softwareentwickler den Gedanken einer Investition nicht schon viel mehr nutzen. Investitionsrechnungen sind keine neue Erfindung, und Software ist ein Asset, in das Geld investiert wurde. In diesem Zusammenhang davon zu sprechen, dass Schulden entstehen, mutet eigentlich seltsam an.

Bei einem großen Softwaresystem kann das Schätzen für die Qualitätsinvestitionen aufwendig sein. Ebenso kann es schwierig sein, die Änderungswahrscheinlichkeit einzelner Komponenten oder Klassen zu bestimmen. Daher ist ein Werkzeug entstanden, das bei der Schätzung helfen soll und einen besseren Überblick über eine Codebasis ermöglicht: das unter der GPL stehende CodeQ Invest [3].

Ein Vorteil des Tools ist die Unterstützung bei der Schätzung der Änderungswahrscheinlichkeiten. Sie lässt sich als Wert direkt schätzen oder auf Basis der Historie des Versionskontrollsystems bestimmen. Dabei wird davon ausgegangen, dass vergangene Änderungen eine Aussage über zukünftige ermöglichen – das ist natürlich nicht immer der Fall. Wenn das Team daher eine manuelle Schätzung für einzelne Dateien, Pakete oder Module angibt, wird stattdessen diese als Änderungswahrscheinlichkeit verwendet. Eine von 100 Prozent bedeutet dabei, dass jede betrachtete Datei auf jeden Fall geändert wird. Da die Änderungswahrscheinlichkeit über das Eintreten der Nichtsanierungskosten bestimmt, ist dieser Faktor in die Gewinnrechnung einzubeziehen:

Gewinn = NRC * Änderungswahrscheinlichkeit – RC

Bei CodeQ Invest formuliert das Team Qualitätsanforderungen, die ein gewünschtes Qualitätsoptimum ausdrücken. Damit die Analyse einer Codebasis mit einer Menge an Qualitätsanforderungen automatisch erfolgen kann, sind die Anforderungen in Form eines Grenzwerts einer Metrik definiert. Um beim Beispiel von oben zu bleiben, müsste für das Bestellsystem eine Qualitätsanforderung existieren, die aussagt, dass die Testabdeckung nicht kleiner als beispielsweise 80 Prozent sein darf. Ebenso werden für jede Qualitätsanforderung die Sanierungs- und Nichtsanierungskosten geschätzt. Wichtig ist, dass die betrachteten Zeiträume und Komponenten nicht zu klein sind. Ansonsten entsteht später der Eindruck von Mikromanagement. Mit den hinterlegten Qualitätsanforderungen werden die Codedateien eines gegebenen Softwaresystems automatisch analysiert. Damit liegen alle benötigten Schätzungen vor.

CodeQ Invest aggregiert alle Kostenwerte,Schätzungen und Gewinne in verschiedenen Sichten. Eine zoombare Tree Map zeigt die Codebasis und das Investitionspotenzial in unterschiedlicher Tiefe, und Säulendiagramme ermöglichen den Vergleich verschiedener Investitionsbeträge anhand des ROIs (Abb. 3).

Projektansicht von CodeQ Invest: Links wird das Investitionspotenzial der Codebasis in Form einer Tree Map visualisiert, und es lassen sich manuelle Schätzungen abgeben. Rechts werden die ROIs für unterschiedliche Investitionsbeträge und ein Qualitätsverbesserungsplan für die Behebung von Qualitätsmängeln angezeigt (Abb 3).

Projektansicht von CodeQ Invest: Links wird das Investitionspotenzial der Codebasis in Form einer Tree Map visualisiert, und es lassen sich manuelle Schätzungen abgeben. Rechts werden die ROIs für unterschiedliche Investitionsbeträge und ein Qualitätsverbesserungsplan für die Behebung von Qualitätsmängeln angezeigt (Abb 3).

Derzeit lässt sich CodeQ Invest in Java-Projekten einsetzen. Zuvor muss allerdings SonarQube [4] installiert sein, damit sich die Metrikwerte laden lassen. Zur Bestimmung der Änderungswahrscheinlichkeit auf Basis der Versionskontrolle wird bislang Subversion unterstützt.

CodeQ Invest ist ein Mittel, das bei der Umsetzung von Qualitätsinvestitionen helfen kann. Im Kern sind nach wie vor Schätzungen nötig, die das Team tätigen muss. Die vom Werkzeug ermittelten Werte hängen davon ab, welche Werte man für die RCs und NRCs der einzelnen Qualitätsmetriken einstellt und gegebenenfalls von der manuell abgeschätzten Änderungswahrscheinlichkeit. Vor einem Einsatz von CodeQ Invest ist abzuwägen, wie die Einführung von Qualitätsinvestitionen besser funktioniert: mit groben manuellen Schätzungen für große Aufräumarbeiten (top down) ohne Tool-Unterstützung oder mit einem Tool, wobei die Schätzung "bottom up" funktioniert. Auf jeden Fall kann das Tool einen interessanten Einblick in die Qualität und die Änderungshistorie des Systems bieten.

Obwohl die Metapher der "technischen Schulden" breit genutzt wird, ist sie nicht konstruktiv: Sie weist zwar auf Probleme hin, aber gibt keine Hinweise, wie sich diese lösen lassen. Sie misst lediglich die Qualität des Codes. Und diese Information ist völlig irrelevant, bis der Code zu ändern ist. Dann ist die Qualität aber entscheidend.

Um mit diesem Problem umzugehen, bietet sich die Metapher der Qualitätsinvestition an: Jede Verbesserung verursacht einen Aufwand. Sie ist nur sinnvoll, wenn dieser Aufwand absehbar bei Änderungen an den Codes durch die höhere Qualität wieder eingespart wird. Diese Betrachtung kann entweder Basis einer Abschätzung sein, oder sie lässt sich durch CodeQ Invest unterstützen. Auf jeden Fall wird so die Basis für einen ökonomisch sinnvollen Umgang mit Softwarequalität gelegt, sodass Entwickler und Management an einem Strang ziehen können.

Eberhard Wolff [5]
arbeitet als freiberuflicher Architekt und Berater. Außerdem ist er ist Java Champion und Leiter des Technologie-Beirats der adesso AG. Sein technologischer Schwerpunkt liegt auf Spring, NoSQL und Cloud.

Felix Müller [6]
arbeitet als IT Consultant und Softwareentwickler bei der codecentric AG. Er beschäftigt sich mit der Entwicklung von Webanwendungen im Java-Umfeld. Dabei interessieren ihn besonders Testautomatisierung, Continuous Delivery und agile Vorgehensweisen.

(ane [8])


URL dieses Artikels:
https://www.heise.de/-2063864

Links in diesem Artikel:
[1] http://www.infoq.com/articles/managing-technical-debt
[2] http://www.sqale.org
[3] http://codeq-invest.org
[4] http://www.sonarqube.org/
[5] http://ewolff.com
[6] http://cupofjava.de
[7] https://www.heise.de/hintergrund/Einsatz-von-SonarQube-zur-Qualitaetssicherung-in-heterogenen-Projekten-1953460.html
[8] mailto:ane@heise.de