Technische Schulden erklärt am Beispiel eines beinahe gescheiterten Videospiels - Cape Of Good Code

Geschrieben von Konstantin Sokolov | 30.06.21 13:40

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.

Fangen wir zunächst mit einer Art “offiziellen” Definition an

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!

Weiße Streifen am Heck setzen MGs eines Jagdflugzeugs außer Gefecht – Eine Geschichte über Technische Schulden

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.

Die Farbstreifen blockieren die eigenen Bordwaffen

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.]

Lasst uns die Schusskraft erhöhen

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.]

Vernichten wir alles und jeden

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.

Die “Lösung”

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.]

Was lernen wir daraus?

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:

  1. Technischen Schulden entstehen durch Zweckentfremdung von Konzepten. 
  2. Das Tückische: Ob man tatsächlich eine Zweckentfremdung begeht oder etwas bestimmungsgemäß gebraucht, ist häufig nicht auf der ersten Blick erkennbar und stellt sich erst im Nachhinein hinaus. 
  3. Softwareentwicklung ist aufgrund der schier unendlichen Anzahl möglicher  Lösungswege besonders anfällig einen einmal eingeschlagenen Lösungsweg bis zum Ende auf die eine oder andere Weise zurechtzubiegen. 
  4. Zeitdruck und ungeplante Aufgaben sind ein wichtiger Faktor bei der Entstehung von Technischen Schulden.
  5. Entscheidungen, die auf bereits vorhandene Technischen Schulden basieren, gleichen einem Kartenhaus. Bewusste und unbewusste Zweckentfremdungen bauen aufeinander auf, überdecken einander und sind miteinander verknüpft. Eine Weile bleibt das Haus stehen, aber jede weitere Karte kann es zum Einsturz bringen
  6. Nicht korrigierte Technische Schulden führen zu eskalierenden Wartungs- und Entwicklungskosten 
  7. Ab einer bestimmten Größenordnung werden Technischen Schulden auch für Kunden zu einem Problem, weil sich Features verzögern, fehlerbehaftet sind oder sich neue gar nicht mehr realisieren lassen.

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. 

Referenzen

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?