Die Broken-Windows-Theorie: Null Toleranz für Softwarequalität

Seite 2: Einwände gegen das Aufräumen

Inhaltsverzeichnis

Das erste typische Gegenargument lautet:

"Ach, das sind doch alles nur Kleinigkeiten!"

Genau diesen Einwand habe ich eben schon vorweggenommen. Interessant ist aber, dass es zahlreiche solche Bedenken gibt. Hier sind wir an dem Punkt, dass sich viele Unternehmen die Problematik schönreden. Und was sind verbreitete Einwände?

Sehr verbreitet ist beispielsweise:

"Ja, grundsätzlich stimmt das alles, aber wir haben keine Zeit. Wir müssen eine Deadline einhalten."

Diese Aussage lässt sich üblicherweise auf zwei Situationen zurückführen:

  • Erstens könnte irgendjemand zu viel versprochen haben, was jetzt eingelöst werden soll: Sales, Marketing oder vielleicht sogar der Product Owner. Hätte niemand überstürzt versprochen, was noch gar nicht fertiggestellt ist, gäbe es nun keine enge Frist. Insofern handelt es sich oftmals um eine schwache Ausrede für eine misslungene (oder gar fehlende) Planung. Und diese schlechte Planung belastet nun das Entwicklungsteam.
  • Zweitens könnte es um gesetzliche Fristen gehen, also Vorgaben, die bis zu einem bestimmten Datum umgesetzt sein müssen. Das liegt dann nicht unbedingt in Ihrem Einflussbereich, wurde also nicht aktiv herbeigeführt. Doch auch hier ändern sich Gesetze meistens nicht von einem Tag auf den anderen, und man hat häufig zumindest eine gewisse Vorlaufzeit, in der zwar nicht alles, aber schon vieles absehbar ist. Hätten Sie eine Codebasis, in der Änderungen rasch, unkompliziert und zielgerichtet vorgenommen werden können, gäbe es weniger Probleme. Wenn aber Teile des Projekts bereits seit Jahren verrotten, also sprichwörtlich Fensterscheiben seit Ewigkeiten zerbrochen sind, dann fällt es jetzt bei dieser konkreten gesetzlichen Anforderung schlicht auf. Somit entsteht ein Problem, das lange ignoriert wurde, sodass Sie nun damit leben müssen.

Ein weiteres häufiges Gegenargument lautet:

"Regelmäßige Codepflege können wir uns nicht leisten, das wäre zu teuer!"

Auch das ist nicht haltbar, denn hier zeigt sich, dass das eigentliche Problem schon vor etlichen Jahren seinen Lauf nahm. Codepflege ist nämlich nur dann kostspielig, wenn sie zu lange hinausgezögert wurde. Natürlich gibt es Bereiche, die mehr Aufwand bedeuten, doch wenn Sie diese von Beginn an zeitnah erledigen, fallen die Kosten viel niedriger aus, als wenn Sie sie wiederholt vertagen, um sie irgendwann inmitten anderer dringender Aufgaben angehen zu müssen, ohne Zeit und Planung.

Vergleichbar ist das mit einem Haushalt, der nie aufgeräumt wird, stets mit dem Argument, es sei jetzt zu viel Aufwand, bis Sie irgendwann gar kein sauberes Geschirr mehr besitzen und die Wohnung voller Müll liegt, sodass Sie darüber stolpern, hinfallen und sich verletzen. Genau in diesem Moment stellen Sie fest, dass gerade in der Küche ein Feuer ausgebrochen ist, weil dort unbeaufsichtigt ein Topf auf dem Herd stand. Und schon wird die Angelegenheit richtig teuer, womöglich erfordert sie sogar eine Renovierung. War der Plan "sofortiges Aufräumen ist zu viel Aufwand" also wirklich so sinnvoll? Ganz bestimmt nicht.

Gerne wird auch argumentiert:

"Alles funktioniert doch im Großen und Ganzen – wir werden tätig, sobald tatsächlich etwas kaputtgeht."

Das wird gerne noch mit "Never Touch a Running System" unterstrichen. Selbstverständlich sollten Sie nicht ohne konkreten Anlass an funktionierendem Code herumbasteln. Aber es geht nicht ums bloße "Herumbasteln", sondern darum, vorhandene technische Schulden abzutragen, um langfristige Schäden zu vermeiden. Häufig steckt hinter diesem Einwand schlicht die Sorge, bei Umbauten könnte etwas kaputtgehen. Und diese Angst ist in gewisser Weise berechtigt. Doch woher rührt sie? Liegt es daran, dass zu wenige automatisierte Tests existieren? Oder vielleicht gar keine? Gibt es auch kein strukturiertes Testkonzept?

In einem solchen Kontext würde wohl niemand unnötige Änderungen riskieren. Dennoch sollte es normal sein, Code zu revidieren, zu überarbeiten und anzupassen. Die einzige Möglichkeit, sicherzustellen, dass dabei nichts zerbricht, sind umfangreiche Tests, am besten automatisiert, damit sie jederzeit effizient wiederholbar sind. Dass viele Projekte darauf weitgehend verzichten, liegt oft daran, dass jemand meinte, Tests seien zu aufwendig und deshalb nicht so wichtig.

Ein weiteres verbreitetes Argument lautet, dass es zu viel Druck aus dem Fachbereich gäbe. Meistens sind das schlicht unrealistische Erwartungen, verbunden mit wenig Verständnis für die Abläufe in der Softwareentwicklung. Das ist grundsätzlich nachvollziehbar: Denn woher soll ein Fachbereich ohne technische Vorerfahrung es besser wissen? Häufig fehlt dann eine Person, die die Interessen der Entwicklung angemessen vertritt und erklärt, wie Softwareentwicklung funktioniert.

Dieser Effekt zeigt sich meist in Unternehmen, deren Kerngeschäft nicht die Softwareentwicklung an sich ist, sondern beispielsweise in Versicherungen, Baukonzernen, dem Einzelhandel und so weiter, wo Software nur ein notwendiges, aber ungeliebtes Hilfsmittel ist. Dort gilt meist "Umsatz vor Grundsatz". Der Fachbereich setzt sich also oft durch, sodass die Softwareentwicklung mit ihren Qualitätsansprüchen außen vor bleibt. Wird dies nicht klar kommuniziert, entsteht massiver Druck von dieser Seite.

Man könnte diese Liste beliebig fortsetzen, aber ich denke, hier wird bereits ein Muster deutlich. Das Muster lautet: Kurzfristiges Denken hat zu oft Vorrang vor langfristigen Überlegungen. Viel zu häufig geht es um eine rasche, günstige Fertigstellung, ohne den Blick auf langfristige Stabilität und Wartbarkeit. Dieses Problem entsteht nicht erst nach und nach, sondern es existiert meist schon ab dem ersten Tag eines Softwareprojekts, bleibt anfangs aber unbemerkt.

Jeder Schritt, bei dem nicht auch an die spätere Weiterentwicklung gedacht wird, führt in die falsche Richtung. Das resultiert unweigerlich in zerbrochenen Fenstern. Wenn es dann wirklich brennt, möchte niemand eine abrupte Kehrtwende vornehmen, denn schließlich hat doch bis gestern scheinbar alles funktioniert. Das Hinauszögern setzt sich also fort, und das Problem verschlimmert sich noch mehr. Erst wenn irgendwann unübersehbar ist, dass es so nicht weitergehen kann, folgt das große Klagen und die Hoffnung, nun eine einfache Lösung zu finden. Doch eine solche existiert nicht – und das will dann verständlicherweise niemand hören.

Welche Lehre lässt sich aus all dem ziehen?

the next big thing – Golo Roden
the next big thing – Golo Roden

Golo Roden ist Gründer und CTO von the native web GmbH. Er beschäftigt sich mit der Konzeption und Entwicklung von Web- und Cloud-Anwendungen sowie -APIs, mit einem Schwerpunkt auf Event-getriebenen und Service-basierten verteilten Architekturen. Sein Leitsatz lautet, dass Softwareentwicklung kein Selbstzweck ist, sondern immer einer zugrundeliegenden Fachlichkeit folgen muss.

Erstens: Wenn Sie früh genug dran sind und Ihr Projekt noch auf der sprichwörtlichen grünen Wiese beginnt, sollten Sie von Tag 1 an eine echte Null-Toleranz-Strategie im Hinblick auf Codequalität verfolgen. Das bedeutet, Sie benötigen ein äußerst strenges Projektsetup. Dazu gehören beispielsweise streng konfigurierte Linter-Regeln, automatisierte Formatierung, angemessene Tests sowie eine CI/CD-Pipeline. Es dürfen keinerlei Warnungen von Linter oder Compiler akzeptiert werden: Entweder ist der Code rundum fehlerfrei, oder der Build schlägt fehl. Dazwischen gibt es nichts.

Ebenso sollte kontinuierliches Refactoring einen hohen Stellenwert haben, und Fehler sollten sofort beseitigt werden. Natürlich wird es niemals vollkommen fehlerfreie Software geben, doch sobald ein Fehler bekannt ist, genießt dessen Behebung oberste Priorität. Solange dieser Bug nicht korrigiert ist, wird kein neues Feature entwickelt, eben konsequent gemäß dem Prinzip "Null Toleranz".

Falls nun jemand behauptet, dies wäre ein Freibrief für die Entwicklung, sich in Details zu verlieren, ist das wahre Problem nicht die Null-Toleranz-Strategie, sondern tief sitzendes Misstrauen gegenüber dem Verantwortungsbewusstsein der Entwickler. Das ist ein viel grundlegenderes Thema, das gern ignoriert wird, weil es wesentlich einfacher scheint, Symptome zu bekämpfen als Ursachen.

Zweitens sollten Sie alles, was möglich ist, automatisieren: Tests, Deployments, Updates und so weiter. Letztlich greift hier alles ineinander. Stellen Sie sich vor, es erscheint ein Update für eine Abhängigkeit: Zunächst müssten Sie erfahren, dass es dieses Update gibt. Danach müssten Sie es testweise einspielen, prüfen, ob weiterhin alles funktioniert, einen Branch erstellen, den Commit vornehmen, pushen, einen Pull-Request anlegen und jemanden finden, der das Ganze prüft und freigibt. Natürlich wird sich niemand regelmäßig diesen Aufwand antun wollen.

Wenn jedoch ein Bot automatisch einen Pull-Request stellt, der dann eine CI/CD-Pipeline anstößt und sämtliche Tests ausführt, Sie über die Ergebnisse informiert werden, und Ihre einzige Aktion (zumindest in 95 Prozent der Fälle) darin besteht, den erfolgreich durchgelaufenen Pull-Request durchzuwinken, dann bleibt Ihr Zeitaufwand minimal. Gleichzeitig bleiben Ihre Dependencies auf dem aktuellen Stand, und Sie haben nun auch die zeitlichen Kapazitäten, sich um jene 5 Prozent zu kümmern, bei denen tatsächlich manuelles Eingreifen nötig ist, etwa wegen Breaking Changes. Dies funktioniert aber nur, wenn Sie die betreffenden Prozesse entsprechend automatisiert haben.

Damit komme ich zum letzten Punkt, den ich Ihnen heute mitgeben möchte: Code-Reviews und das Vier-Augen-Prinzip ab Tag 1. Nur so ist sichergestellt, dass jede Änderung geprüft wird und es zudem kein Inselwissen gibt. Nach einem Review haben zumindest zwei Personen den Code durchgesehen und sich damit auseinandergesetzt. Alternativ können Sie auch Pair-Programming nutzen, denn das ist im Grunde lediglich ein Live-Review. Wahrscheinlich hören Sie jetzt schon das Argument, dass dies zu kostenintensiv sei und keine Zeit dafür bleibe, wegen Deadlines, Fachbereich und so weiter. Aber vielleicht haben Sie durch diesen Blogpost ein paar Argumente an der Hand, um all dem zukünftig souveräner zu begegnen.

Unter dem Strich bleibt die Erkenntnis, dass eine dauerhafte, regelmäßige Pflege des Codes langfristig zu weit stabileren und damit auch günstigeren Projekten führt, selbst wenn es anfangs gegen die Intuition sprechen mag. (rme)