Der Begriff der “Technischen Schulden” ist eine sehr nützliche Metapher. Sie hilft, bestimmte problematische Eigenheiten der Softwareentwicklung anschaulich zu machen.
Ungeachtet der scheinbaren Anschaulichkeit des Begriffs habe ich immer wieder das Gefühl, dass Personen, die nie unmittelbar mit Softwareentwicklung zu tun hatten, die tatsächliche Größenordnung der Problematik von Technischen Schulden nicht in vollem Umfang nachvollziehen können. Für Verantwortliche in Softwareentwicklungs-Projekten wäre das aber sehr wünschenswert.
Im Folgenden werde ich versuchen dieses wichtige Thema einfach und nachvollziehbar darzustellen. Ich hoffe es trägt zum Verständnis bei, wie zu hohe Technische Schulden die Zukunft einer Software zerstören können.
Technische Schulden sind die beabsichtigten als auch die unbeabsichtigten Verstöße gegen gute Architektur- und Codierungspraktiken. Diese Schulden verursachen zunehmenden Aufwand und Kosten, um die Software zu warten, zu erweitern oder zu erneuern.
Weniger technisch formuliert, aber ebenso zutreffend ist:
Die ganze Chaos, dass man hinterlässt, wenn man denkt, dass man fertig ist.
Die Vielfalt der Lösungswege bei der Entwicklung von Software übersteigt alles, was man aus der alltäglichen Welt der Dinge kennt. Und so unterschätzt man als Nicht-Entwickler möglicherweise das schier unendliche Spektrum der denkbaren “beabsichtigten und unbeabsichtigten Verstöße”, zu denen die Softwareentwicklung einen verleiten kann. Durch Zeit-, Budgetdruck oder auch Inkompetenz steckt eine Software stets voller Imperfektionen. Und obwohl sie tut was sie soll, addieren sich diese Imperfektionen im Lifecycle und werden ohne Gegenmassnahmen zu einer Belastung für die Weiterentwicklung, die irgendwann unüberwindbar wird, sei es technisch oder ökonomisch
Eine weitere Definition würde nicht helfen und so möchte ich es mit einer Geschichte versuchen. Ob sie tatsächlich so passiert ist, kann ich nicht sagen. Sie ist aber derart plausibel und nachvollziehbar für ITler in der Softwarebranche, dass sie sehr realistisch erscheint.
Der folgende Text ist eine freie Übersetzung dieser russischen Originalquelle, welche einen kommentar-basierten Austausch zwischen verschiedenen Stakeholdern (aus der Entwicklung, der Qualitätssicherung und dem Projektmanagement) in einem Softwareprojekt wiedergibt.
Los geht’s!
Stellen Sie sich vor Sie sind Projektmanager und bauen ein historisches Jagdflugzeug in einem Videospiel nach. Nach den ersten Testflügen bemerken Ihre Kunden jedoch eine Ungenauigkeit im Vergleich zum Original: es fehlen zwei weiße Streifen am Heck.
Sie übertragen die Angelegenheit an Ihren QA-Manager, welcher diese wiederum an einen QA-Ingenieuer weiterleitet. Dieser delegiert die Aufgabe an den Art Director, so dass sie schließlich bei einem Texturen-Designer landet.
Der Texturen-Designer überträgt die finale Erstellung der Streifen an einen 2D-Designer. Dieser entgegnet jedoch, dass das Team komplett überlastet sei und die Streifen nicht früher als in zwei Monaten erstellt werden können. Daraufhin wendet sich der Texturen-Designer an das weniger überlastete 3D-Designer-Team. Er berichtet, es sehe ganz danach aus, als seien die exakt-benötigten Texturen so zeitnah nicht hinzukriegen und bittet um die Modellierung der Streifen auf der Grundlage bereits verfügbarer, am besten passender Texturen.
[Mit diesem Verstoß gegen architektonische Best Practices – d.h. einer Zweckentfremdung – beginnen hier die neuen Technischen Schulden.]
Neun Tage später setzt der 3D-Designer den Lead-Entwickler über die Fertigstellung der weißen Streifen in Kenntnis. Der letzte Schritt sei bloß noch die Anbringung der Streifen an das Flugzeug. Der Lead-Entwickler beauftragt einen Junior-Entwickler mit der Durchführung. Einen Monat später verkündet dieser die Fertigstellung.
Nach nur zwei weiteren Tagen meldet der QA-Ingenieur einen Defekt der Bord-Maschinengewehre: es könne niemand mehr abgeschossen werden.
Es vergehen anderthalb Monate bis der Senior-Entwickler das Problem festnageln kann: Die Streifen verdecken die MGs und bestehen ihrerseits aus einem Material, welches die Kollisionserkennung für Geschosse in sich trägt. Die Maschinengewehr-Kugeln können die Streifen nicht durchdringen. Der Lead-Entwickler versteht nicht, wie es sein kann, dass die Streifen die MGs verdecken, obwohl sie doch am hinteren Teil des Rumpfes angebracht sind. Der Senior-Entwickler klärt auf, dass sich die echten MGs tatsächlich eben im hinteren Teil befinden und die MGs in den Flügeln bloß Fakes seien, nur zum Schein. Es wäre projekthistorisch bedingt, an die genauen Gründe erinnere er sich nicht mehr. Jedenfalls hinge die komplette Ballistik von diesem Design ab. Eine Überarbeitung würde zu viel Zeit in Anspruch nehmen.
[Hier treffen neue Technische Schulden auf alte. Man kann sich vorstellen, dass eine vollständige Dokumentation dieses neue Problem früher erkennbar gemacht und die Entwicklung möglicherweise in eine richtige Bahn gelenkt hätte.]
Nach drei Wochen wendet sich der Lead-Entwickler an den 3D-Designer mit der Bitte, die kollisionsverursachenden Bestandteile aus den weißen Streifen zu entfernen. Dieser entgegnet, dies sei nicht möglich, da die Kollisionsmerkmale inhärente Eigenschaften der Texturen seien und zur Zeit keine anderen Texturen zur Verfügung stünden. Die weißeste Textur, die er finden konnte, stamme von einer Stelle eines anderen Flugzeugs, welche zufälligerweise mit einer 4cm starken Panzerung ausgestattet ist.
[Bingo, Ihr könnt euch vorstellen, dass man ab hier hätte umkehren müssen, tat man aber nicht.]
Der Lead-Entwickler ist fassungslos über die Festverdrahtung der Kollision in den Texturen und fragt den Senior-Entwickler, ob es nicht möglich sei, diese durch eine separate Einstellung abzubilden. Dieser weiß nicht wie das gehen sollte, da auch die Materialermüdung, für eine realitätsnahe Implementierung der Kugel-Durchdringung, in den Alpha-Channels der Texturen codiert ist.
Das Hin und Her dauert zwei weitere Monate bis sich der Spieler Community-Manager meldet und die Priorität der Angelegenheit auf HIGH hochstuft: die Spieler hätten abermals bemerkt, dass die Streifen fehlen und würden das Interesse an einem derart dilettantischen Spiel verlieren. Das Projekt sei am Rande des Scheiterns.
Der Lead-Entwickler reagiert schnell und bittet um die Verschiebung der Streifen, so dass diese die MGs nicht mehr verdecken. Damit ist jedoch der historische Fachberater keinesfalls einverstanden: alle Details seien millimetergenau anhand von historischen Fotos abgemessen, eine Veränderung würde er auf keinen Fall mittragen.
Der Lead-Entwickler resigniert und fragt den Senior nach irgendeiner Lösung, damit es endlich funktioniert. Die Situation sei aussichtslos. Der Senior entscheidet, die Schussstärke der MGs von 2 auf 231 zu erhöhen. So würden 229 Einheiten für die Durchschießung der Streifen aufgebraucht, und die restlichen 2 für die gewohnte Flugbahn der Kugeln verbleiben.
[Das ist eine typische situative (Fehl-)Entscheidung, die den Softwareentwicklern alsbald um die Ohren fliegen wird.]
Der Senior-Entwickler schließt die Angelegenheit nach zwei Monaten und vermeldet, es sollte nun alles in Ordnung sein. Dem hat der QA-Lead jedoch nach einem weiteren Monat vehement etwas entgegen zu setzen. Er berichtet erbost, dass die Schusskraft eines anderen Flugzeugmodells nun derart erhöht ist, dass es alles und jeden mühelos vernichtet, was absolut nicht hinnehmbar sei.
Dem Game-Designer ist die Problematik sofort klar. Das andere Modell verwendet die gleichen MGs, jedoch zehnfach skaliert. Die Form der MGs beider Modelle sei ähnlich und so hätte man seinerzeit entschieden, an einer zusätzlichen Modellierung zu sparen. Die Schusskraft skaliert ebenfalls automatisch, jedoch mit einem Faktor von 1000, proportional zum Durchmesser des Laufs, was letztendlich zu einer gewaltigen Schusskraft führt.
Der Senior gibt daraufhin zu verstehen, dass die komplette Architektur der Game-Engine geändert werden müsse, um eine dynamische Kollisionsanpassung der Texturen zu ermöglichen, was ein halbes Jahr Arbeit bedeuten würde. Der Lead-Entwickler weiß, dass solche Entscheidungen nur auf höchster Ebene getroffen werden könnten und übergibt an den Projektmanager.
Der Projektmanager teilt daraufhin mit, er habe beschlossen, dass es einfacher ist, den Kritiker, der die Ungenauigkeiten bzgl. der weißen Streifen bemängelt hatte, aus der Community zu entfernen. Die Sache mit den Streifen habe sich damit erledigt, alle sollen ihren üblichen Aufgaben nachgehen. Er würde sich nun überlegen, wie er den Ausschluss begründen kann.
[In diesem Fall die einzig richtige Entscheidung. Es wurden hier durch Zeit- und Budgetdruck in kurzer Zeit soviel Technische Schulden aufgebaut, dass eine Weiterentwicklung des Spiels kaum noch hätte geleistet werden können.]
Technische Schulden vernichten geleistete Entwicklungsarbeit. Und zwar häufig weitaus mehr als entsprechende Verbesserungsmaßnahmen oder schuldenfreie Lösungen beansprucht hätten. Im vorliegenden Fall steht das Team nach 12 Monaten wieder auf Los ohne einer Lösung des eigentlichen Problems. Die beiden sinnvollen Alternativen – 2 Monate zu warten oder eine umfangreiche Verbesserung innerhalb von 6 Monaten durchzuführen – wurden abgelehnt.
Fehlentscheidungen offenbaren sich aber meist erst in der Retrospektive und sind trotz Expertise der Fachkräfte häufig nur schwer vorhersehbar.
Zum Schluss eine Zusammenfassung wichtiger Charakteristika der aufgebauten Technischen Schulden in diesem Beispiel:
Das Wichtigste: Technischen Schulden lassen sich nicht a-priori vermeiden. Aber sie können durch Beachtung von Best Practices in den Entwicklungsprozessen und regelmäßige Beurteilungen und Anpassungen der Architektur unter Kontrolle gehalten werden.
[1] dzuikaku.txt: http://yadi.sk/d/wcByE6pH6VTjP (Originalquelle)
Mehr zum Thema der Technischen Schulden, insbesondere wie diese über das Bauchgefühl hinaus im Code gemessen und quantifiziert werden können, finden Sie in unserem Blog: Corona-Warn-App – Auf dem Weg zu kritischen Technischen Schulden?