Softwareerosion im Fokus
Softwareverschleiß versus technische Schulden
Während der Softwareentwicklung kommt unweigerlich der Zeitpunkt, ab dem die Architektur einer Software zu erodieren beginnt. Dieser Prozess schleicht sich meist heimlich ein und erst wenn eine kritische Masse erreicht oder überschritten ist, fällt uns als Softwareentwicklern das Problem bewusst auf. Carola Lilienthal führt die Ursachen der Softwareerosion auf die folgenden vier Phänomene zurück [1]:
- Das Phänomen „Programmieren kann jeder“
- Die Architekturerosion steigt unbemerkt
- Komplexität und Größe von Softwaresystemen
- Das Unverständnis des Managements und der Kunden für Softwareentwicklung
Das erste Phänomen tritt ein, wenn unerfahrene Softwareentwickler lokale Architektur- oder Entwurfsideen umsetzen, ohne dabei die Gesamtarchitektur zu berücksichtigen. Die unbemerkte Architekturerosion (Phänomen 2) tritt auf, wenn die geplante Architektur den steigenden Anforderungen nicht mehr gerecht wird, Entwickler entsprechende Anpassungen aus Zeit- oder Kostengründen jedoch unterlassen. Die Komplexität und Größe von Softwaresystemen steigt mit der Komplexität des Anwendungsproblems (s. Phänomen 3). Üblicherweise versuchen Entwickler einfache Lösungen für komplexe Probleme zu finden, was aber nicht immer gelingt. Das letzte Phänomen entsteht aus der Problematik, dass Entwickler die Softwareerosion ihren Kunden gegenüber kommunizieren und Zeit sowie Geld für Architekturanpassungen begründen müssen. Diesem Phänomen widmet sich der vorliegende Beitrag.
Haben Entwickler die Softwareerosion erkannt, möchten sie die Software gerne überarbeiten (refactorn). Denn als Entwickler wissen wir, ohne Refactorings werden Änderungen und Erweiterungen der Software schwierig und teuer. Wenn ein Entwicklungsteam die Refactorings über eine längere Zeit ignoriert, beansprucht die Wartung und Erhaltung einer Software stetig mehr Zeit. Dem Entwicklungsteam bleibt immer weniger Zeit, neue Anforderungen umsetzen.
Abbildung 1: Steigende Pflegekosten einer Software [1]
Refactorings motivieren, aber wie?
Bevor es jedoch soweit kommt, wollen und müssen Entwickler und Projektleiter ihre Kunden davon überzeugen, dass Refactorings sinnvolle Maßnahmen sind, die zu einer Verbesserung der Software führen. Diese Aufgabe ist nicht einfach, denn Refactorings verursachen zunächst Kosten und erzeugen in der Regel keinen fachlichen Mehrwert. Die Vorteile von Refactorings spüren die Kunden nur sehr indirekt, wenn sie beispielsweise langfristig mehr fachliche Anforderungen realisieren können. Diese Gründe führen dazu, dass Refactorings schwer vermittelbare Kandidaten sind.
Um den Nutzen von Refactorings stärker in der Sprache der Kunden zu beschreiben, wurde in der Softwaretechnik der Begriff der technischen Schuld geprägt [2]. Nach Cunningham können geringfügige technische Schulden die Entwicklung kurzzeitig beschleunigen, z.B. wenn Entwickler einen Shortcut (oder Hack) einbauen, um eine Aufgabe schneller zu lösen. Solange der Shortcut durch Refactorings zeitnah wieder ausgebaut und damit die technische Schuld beglichen wird, spricht nichts gegen dieses Vorgehen. Gefährlich wird es, wenn Schulden nicht zurückgezahlt werden und Entwickler auf erodierter Code-Basis neue Anforderungen umsetzen. Dann entstehen Zinses-Zins-Effekte, die eine Weiterentwicklung behindern oder gar unmöglich machen [2]. Jeder Kunde sollte daher verstehen, dass technische Schulden lieber kurz- als mittelfristig abgebaut werden müssen und diese Aufgabe zwingend erforderlich ist.
Das Problematische an Schulden ist der Begriff an sich
Schwierig an technischen Schulden ist der damit einhergehende psychologische Effekt. Projektleiter können dem Kunden ein- oder zweimal glaubhaft vermitteln, dass das Team technische Schulden aufgenommen hat. Beim dritten oder spätestens vierten Mal wird die Sache schwieriger. Denn im Alltag versucht jeder Mensch unnötige Schulden zu vermeiden, indem er betriebswirtschaftlich clever agiert.
Nun stellt sich die Frage, welchen Eindruck ein Kunde von einem Entwicklerteam bekommt, das wiederkehrend mit technischen Schulden aufwartet? Allein der Begriff Schuld deutet negativ an, dass ein technisch versiertes Entwicklerteam bei softwaretechnisch korrektem Handeln eine Architekturerosion hätte vermeiden können oder gar müssen. Schulden, ob technische oder betriebswirtschaftliche, haben einen negativen Beigeschmack und sind deshalb in der Kommunikation schwierig. Sie werden in der Wirtschaft meist bewusst in Kauf genommen, um mit der verbundenen Anschaffung mittel- oder langfristig einen Mehrwert zu erzielen. In der Softwareentwicklung werden technische Schulden in der Regel unbewusst aufgenommen und erzielen auch langfristig selten einen Mehrwert.
Der Begriff der technischen Schuld ist negativ belastet. Wie können wir dennoch dem Kunden auf eine einfache und verständliche Weise den Sinn und Nutzen von Refactorings vermitteln? Dabei wollen wir uns als Entwickler nicht rechtfertigen müssen, softwaretechnisch unsauber gearbeitet zu haben.
Der Begriff Softwareverschleiß als Mittel zur besseren Kommunikation
Aus unserer Sicht trifft der Begriff Softwareverschleiß den Nagel besser auf den Kopf. Verschleiß ist ein natürlicher und unaufhaltsamer Prozess, der in jedem produzierenden Gewerbe bekannt ist. Selbst in den modernsten Anlagen mit dem besten Fachpersonal tritt Verschleiß unvermeidlich auf und verursacht Verschleißkosten. Je höher die Produktion in einer Anlage gefahren wird, desto höher sind die Verschleißkosten. Und wer langfristig auf Verschleiß fährt, wird nach einer gewissen Zeit eine neue Anlage erwerben müssen. In technischen Anlagen gehört daher die Wartung zum Alltag dazu, ihr technischer und betriebswirtschaftlicher Nutzen ist unbestritten.
In der Softwareentwicklung kann der Begriff Softwareverschleiß helfen, die Kommunikation zwischen Kunden und Entwicklern zu vereinfachen. Entwickler und Projektleiter können Kunden verständlich machen, dass die Umsetzung vieler fachlicher Anforderungen (ggf. in kurzer Zeit) die Software über die Zeit verschleißen lässt. Das führt zu Verschleißkosten, die über die Zeit steigen. Eine regelmäßige Wartung (Refactoring) kann die Verschleißkosten reduzieren.
Der Vorteil des Begriffs Softwareverschleiß ist, dass er die Schuldfrage von den Entwicklern fernhält. Der Verschleiß ist nicht auf die mangelnden Software-Skills der Entwickler zurückzuführen, sondern auf die umfangreiche Leistung des Teams und den Verbrauch von Ressourcen. Auch wenn in der Software keine mechanische Beanspruchung von Bauteilen existiert, äußert sich Verschleiß durch abnehmende Softwarequalität. Der Softwareverschleiß ist ein natürlicher und unvermeidlicher Prozess. Er wird im Gegensatz zu einer Schuld nicht bewusst in Kauf genommen, sondern tritt in den besten Teams regelmäßig auf. Gute Teams sind in der Lage, den Softwareverschleiß zu erkennen und angemessene Wartungsmaßnahmen durchzuführen. Schlechtere Teams, oder solche, die dazu gezwungen werden, entwickeln Software auf Verschleiß und müssen irgendwann erkennen, dass sie im schlimmsten Fall ihre Software nicht weiterentwickeln können.
Nutzen von Refactorings monetär bewerten
In produzierenden Gewerben können sowohl die Verschleißkosten als auch die Kosten und der Nutzen von Wartung, monetär erfasst und bewertet werden. In der Softwareentwicklung fällt es uns hingegen sehr schwer, den ökonomischen Nutzen oder die Risiken ausbleibender Refactorings zu bewerten. Wir versuchen es meist mit gutem Einreden auf den Kunden, der Darlegung offensichtlicher Argumente, die ein jeder einsehen müsse oder dem Aufzeigen von Schreckensszenarien bei ausbleibender Refactorings.
Gernot Starke, Carola Lilienthal und Peter Hruschka haben im Java Magazin [3] einen Ansatz vorgestellt, wie sie den ökonomischen Nutzen von Refactorings bewerten. Ähnlich der Schätzung von Anforderungen können auch Refactorings in kleine Teile zerlegt und bewertet werden. Die Grundlage für die Bewertung können messbare Ergebnisse wie z.B. Ausführungszeit, Speicherverbrauch oder auch Annahmen sein. Letztere erlauben die Unsicherheit einer Schätzung in eine ökonomische Bandbreite einzuordnen. Je höher die Breite einer Schätzung, desto größer ist die Unsicherheit über die Eintrittswahrscheinlichkeit von Risiken. Wenn ein Kunde beispielsweise erfährt, dass der Verschleiß einer Softwarekomponente monatliche Kosten zwischen 10.000 und 50.000 EUR verursacht, kann er das Risiko für sein Geschäft eigenständig bewerten und entsprechende Entscheidungen treffen.
Während die Schätzung von Anforderungen in der Softwareentwicklung etabliert ist, ist die Schätzung von Verschleißkosten noch keine gängige Praxis. Die Methoden dafür sind mit den Methoden aus der Anforderungsermittlung vergleichbar. Wir brauchen lediglich mehr Übung darin.
Beispiel einer Schätzung von Verschleißkosten
Als Beispiel soll uns eine Client-/Server-Anwendung dienen. Die Architektur der Client-seitigen Software erlaubt es nicht, Remote-Services gegen lokale Dummy-Services auszutauschen. Folglich muss während der UI-Entwicklung die Anwendung beim Start darauf warten, dass ein Remote-Service Daten vom Server abholt und im Client visualisiert. Folgende Messungen und Annahmen sind in unserem Beispiel möglich:
- Die messbare Zeit der Datenübertragung beim Start der Anwendung beträgt 45 Sekunden pro Start.
- Zwei Entwickler arbeiten im Pair zu einem Tagessatz von 800 EUR/Person
- Wir nehmen an, dass die Anwendung 150 Mal pro Tag zur Überprüfung des UI-Layouts gestartet wird
- die Entwicklung der UI-Komponenten wird schätzungsweise acht Wochen beanspruchen.
Daraus resultieren folgende Kosten:
- 800 EUR Tagessatz = 0,028 EUR/Sek.
- 2 Entwickler * 45 Sek * 150 Anwendungsstarts/Tag * 0,028 EUR/Sek = 378 EUR/Tag
- 40 Tage * 378 EUR = 15.120 EUR
Die Verschleißkosten werden sich in den acht Wochen Entwicklungszeit auf 15.120 EUR summieren. Darin ist lediglich die reine Entwicklungszeit eingerechnet. Schätzungsweise 70% der Kosten einer Software entstehen erst nach der Auslieferung, in der Wartungsphase. Diese Kosten müssen wir über die Lebensdauer einer Software ebenfalls einberechnen. Annahmen dazu sind jedoch schon viel schwieriger zu treffen, daher bleiben wir bei den 15.120 EUR. Diesen kann nun der Aufwand für ein Refactoring gegenübergestellt und monetär bewertet werden. Liegt der Refactoring-Aufwand deutlich unter den Verschleißkosten, wird kein Kunde das Refactoring ausschlagen.
Referenzen
[1] Gernot Starke im Geleitwort zu Carola Lilienthal: Langlebige Software-Architekturen, S. VI. dpunkt.verlag 2015
[2] Ward Cunningham: The WyCash Portfolio Management System. Experience Report, OOPSLA 1992
[3] Gernot Starke, Carola Lilienthal, Peter Hruschka: Gegen die dunkle Macht – verbessern, aber richtig. Java Magazin 8/15