Eine Codebase-Health-Scorecard: Metriken, die zeigen, wann Refactoring und wann Rewrite
Hör auf, aus dem Bauch heraus zu streiten
Alle paar Monate passiert irgendwo in einem Softwareunternehmen dasselbe Meeting. Ein Entwickler beschwert sich, dass mit der Codebasis nicht zu arbeiten ist. Eine Führungskraft fragt, ob man sie neu schreiben sollte. Jemand Erfahrenes sagt, Rewrites scheitern immer. Die Diskussion dreht sich eine Stunde im Kreis und endet dort, wo sie begann - bei einer vagen Einigung, "ein paar technische Schulden abzubauen", die niemand umsetzt.
Das eigentliche Problem ist nicht, dass die Codebasis schlecht ist. Das eigentliche Problem ist, dass sie niemand gemessen hat. Die Entscheidung zwischen Refactoring und Rewrite gehört zu den teuersten, die ein Entwicklungsteam trifft, und in den meisten Organisationen fällt sie ohne einen einzigen quantitativen Datenpunkt.
Eine Codebase-Health-Scorecard ändert das. Sie ersetzt Meinung durch Messung und Bauchgefühl durch eine belastbare Zahl. Dieser Beitrag zeigt, welche Metriken in eine praxistaugliche Scorecard gehören, wie du sie ohne Wochen an Aufwand erhebst und was die Werte tatsächlich aussagen.
Was eine Codebase-Health-Scorecard nicht ist
Bevor es um die Metriken geht, eine Klarstellung: Eine Health-Scorecard ist kein Coverage-Report, keine Zusammenfassung statischer Analyse und kein SonarQube-Dashboard. Das sind Eingangsdaten. Die Scorecard verdichtet diese Eingangsdaten zu einer strukturierten Bewertung über mehrere Dimensionen, gewichtet nach ihrer Wirkung auf die konkrete Entscheidung, die du treffen willst.
Das Ziel ist eine einzelne Seite, mit der ein CTO oder ein Technical Lead in ein Stakeholder-Meeting gehen und sagen kann: Hier stehen wir, so sind wir hierher gekommen, und das sagen die Daten über den nächsten Schritt.
Die fünf Dimensionen der Codebase-Health
1. Komplexität und kognitive Last
Das direkteste Maß dafür, wie schwer eine Codebasis zu bearbeiten ist, ist die zyklomatische Komplexität - die Anzahl unabhängiger Pfade durch eine Funktion. Eine Funktion mit einer Komplexität über 10 ist schwer zu durchdringen. Über 20 lässt sie sich kaum noch sicher ändern. Eine Codebasis, deren Durchschnittskomplexität über alle Funktionen über 8 liegt, signalisiert echte strukturelle Probleme.
Kognitive Komplexität, eine Verfeinerung, die Werkzeuge wie SonarQube nutzen, gewichtet verschachtelte Strukturen stärker als einfache Verzweigungen. Sie ist ein besserer Indikator für Entwicklerfrust als rohe zyklomatische Komplexität, weil tief verschachtelter Code schwerer im Kopf zu behalten ist, selbst wenn die reine Anzahl an Verzweigungen moderat bleibt.
Wie du misst: phploc für PHP, radon für Python oder die eingebaute Komplexitätsanalyse in SonarQube. Für JavaScript und TypeScript liefern eslint mit der complexity-Regel oder npm-Pakete wie code-complexity schnell Daten auf Funktionsebene.
Scorecard-Bänder für die Durchschnittskomplexität über die Codebasis:
- Unter 5: gesund
- 5 bis 8: beherrschbar, Trend beobachten
- 8 bis 12: hoch, Refactoring-Priorität
- Über 12: Rewrite-Signal
2. Testabdeckung und Testqualität
Die reine Coverage-Prozentzahl ist die meistzitierte und zugleich am häufigsten missverstandene Metrik. Eine Codebasis mit 85 Prozent Abdeckung kann trotzdem untestbar sein, wenn diese Abdeckung aus Tests besteht, die triviales Verhalten prüfen und die Geschäftslogik komplett ungeprüft lassen.
Wichtiger als der Prozentwert ist die Abdeckung der kritischen Pfade - also des Codes, der Geld verarbeitet, Authentifizierung abwickelt, Daten mutiert oder die zentrale Geschäftslogik trägt. Du kannst 40 Prozent Gesamtabdeckung und eine gesunde Codebasis haben, wenn jeder kritische Pfad abgedeckt ist. Und du kannst 90 Prozent Gesamtabdeckung und eine gefährlich brüchige Codebasis haben, wenn die Tests oberflächlich sind.
Sekundäre Signale, die neben der Abdeckung zählen:
- Mutation Score: Wie viel Prozent absichtlicher Code-Mutationen bringen mindestens einen Test zum Scheitern? Ein Mutation Score unter 50 Prozent deutet darauf hin, dass deine Tests Logik nicht wirklich prüfen.
- Verhältnis Test- zu Produktivcode: Ist deine Testsuite kleiner als der Produktivcode, ist das bei einer gereiften Codebasis meist ein Warnsignal.
- Flaky Tests: Eine Testsuite mit mehr als 2 bis 3 Prozent instabilen Tests untergräbt aktiv das Vertrauen der Entwickler und verdeckt echte Fehler.
Bei einer Codebasis mit nahezu null Testabdeckung lautet die Frage, ob der Code überhaupt testbar ist. Stark gekoppelter Code ohne Dependency Injection, mit Datenbankaufrufen mitten in der Geschäftslogik, lässt sich nicht testen, ohne die Architektur neu zu schreiben - ein Sprint zum Testschreiben reicht dafür nicht.
Scorecard-Bänder:
- Abdeckung kritischer Pfade über 80 Prozent, Mutation Score über 60 Prozent: gesund
- Abdeckung kritischer Pfade 50 bis 80 Prozent, Mutation Score 40 bis 60 Prozent: beherrschbar
- Abdeckung kritischer Pfade unter 50 Prozent oder Mutation Score unter 40 Prozent: hohes Risiko
- Nahezu keine Abdeckung bei Code, der ohne strukturelle Änderungen nicht unit-testbar ist: Rewrite-Signal
3. Zustand der Abhängigkeiten
Abhängigkeiten sind das schleichende Gift in den meisten langlebigen Codebasen. Ein Paket, das 2018 aktuell war, ist nicht nur veraltet - es kann bekannte Sicherheitslücken enthalten, mit aktuellen Framework-Versionen inkompatibel sein und ohne Maintainer aufgegeben worden sein, der künftige Probleme behebt.
Zu erhebende Metriken:
- Veraltete direkte Abhängigkeiten: Wie viele deiner direkten Abhängigkeiten liegen mehr als eine Major-Version hinter dem aktuellen Release?
- Bekannte CVEs:
npm audit,composer auditodersafety check(Python) liefern die Anzahl bekannter Schwachstellen, aufgeschlüsselt nach Schweregrad. - Aufgegebene Pakete: Prüfe für jede Abhängigkeit, ob das Upstream-Repository in den letzten 24 Monaten einen Commit hatte. Ein weit verbreitetes Paket ohne jüngste Aktivität ist ein Risiko.
- Abhängigkeitstiefe: Tief verschachtelte transitive Abhängigkeiten sind schwer zu prüfen und oft nicht unabhängig aktualisierbar. Ein
node_modules-Baum mit 1.400 Paketen für eine mittelgroße Anwendung ist eine Wartungslast.
Der Zustand der Abhängigkeiten ist besonders nützlich als Frühindikator. Eine Codebasis mit gesunder Anwendungslogik, aber 40 veralteten direkten Abhängigkeiten und drei kritischen CVEs steuert auf eine Krise zu, auch wenn sie aktuell funktioniert.
Scorecard-Bänder:
- Keine kritischen CVEs, weniger als 20 Prozent der direkten Abhängigkeiten mehr als eine Major-Version zurück: gesund
- Ein oder zwei kritische CVEs mit geplanter Behebung, 20 bis 40 Prozent veraltete Abhängigkeiten: beherrschbar
- Mehrere kritische CVEs, mehr als 40 Prozent veraltete Abhängigkeiten oder aufgegebene Schlüsselabhängigkeiten: hohes Risiko
4. Change Failure Rate und Deployment-Schmerz
Der Zustand einer Codebasis zeigt sich unmittelbar im Deployment-Verhalten. Eine gut strukturierte, gut getestete Codebasis mit klarer Trennung der Zuständigkeiten hat eine niedrige Change Failure Rate, also einen geringen Anteil an Deployments, die einen Incident auslösen oder ein Rollback erfordern. Eine eng gekoppelte, undurchsichtige und schlecht getestete Codebasis scheitert regelmäßig.
Die DORA-Metriken liefern hier den quantitativen Rahmen:
- Change Failure Rate: Anteil der Deployments, die zu einem Produktionsvorfall führen. Der Branchenwert für leistungsstarke Teams liegt unter 5 Prozent.
- Mean Time to Recovery: Zeit zwischen einem Produktionsausfall und seiner Behebung. Über zwei Stunden ist ein Signal dafür, dass die Codebasis schwer zu debuggen und einzugrenzen ist.
- Deployment-Frequenz: Leistungsstarke Teams deployen mehrmals täglich. Wenn dein Team alle zwei Wochen deployt, weil Deployments riskant sind, ist das ein Gesundheitsproblem der Codebasis.
Am direktesten misst du das über dein Incident-Log und deine Deployment-Pipeline. Werden diese Daten nicht systematisch erfasst, ist schon ihr Fehlen ein Signal.
Scorecard-Bänder:
- Change Failure Rate unter 5 Prozent, MTTR unter einer Stunde: gesund
- Change Failure Rate 5 bis 15 Prozent, MTTR ein bis vier Stunden: beherrschbar
- Change Failure Rate über 15 Prozent oder MTTR regelmäßig über vier Stunden: hohes Risiko
5. Architektonische Kopplung
Kopplung ist die am schwersten automatisch messbare Metrik, aber oft die aussagekräftigste. Eine Codebasis, in der jede Komponente jede andere kennt, lässt sich nicht sicher ändern - eine Anpassung an einer Stelle erzeugt Wellen durch das System, die sich weder vorhersagen noch vorab testen lassen.
Nützliche Näherungen für Kopplung:
- God Classes: Klassen oder Module mit mehr als 500 Zeilen, mehr als 20 öffentlichen Methoden oder Abhängigkeiten zu mehr als 10 anderen Klassen. Ein einfacher Zeilenzähler-Scan, der alles über 400 Zeilen markiert, genügt für die erste Sichtung.
- Zyklische Abhängigkeiten:
madgefür JavaScript,deptracfür PHP und vergleichbare Werkzeuge zeichnen deinen Abhängigkeitsgraphen und markieren zyklische Importe. Schon eine Handvoll Zyklen weist auf strukturelle Probleme hin. - Feature Envy: Code in einem Modul, der überwiegend Daten eines anderen Moduls manipuliert, ist ein Hinweis darauf, dass die Modulgrenzen falsch gezogen sind.
- Querschnittlicher Datenbankzugriff: Wenn Controller, Services und Repositories alle direkte Datenbankaufrufe enthalten, ist die Datenschicht nicht isoliert und lässt sich weder ersetzen noch unabhängig testen.
Bei architektonisch stark gekoppelten Codebasen ist die entscheidende Frage, ob die Kopplung zufällig entstanden ist - mangelnde Disziplin, die sich durch Refactoring beheben lässt - oder strukturell, also in den grundlegenden Designentscheidungen des Systems verankert. Strukturelle Kopplung lässt sich in der Regel nicht ohne einen teilweisen oder vollständigen Rewrite des betroffenen Subsystems auflösen.
Den Score berechnen
Vergib für jede Dimension einen Wert von 1 bis 4 anhand der Bänder oben:
- 4: gesund
- 3: beherrschbar
- 2: hohes Risiko
- 1: Rewrite-Signal
Gewichte die Dimensionen nach ihrer Relevanz für deine Situation. Bei einem Produkt in aktiver Entwicklung verdienen architektonische Kopplung und Change Failure Rate eine höhere Gewichtung. Bei einem System, das im Wesentlichen als Datenspeicher dient, zählen der Zustand der Abhängigkeiten und die Testabdeckung der Datenmutationspfade mehr.
Ein gewichteter Gesamtwert über 14 von 20 spricht dafür, dass die Codebasis grundsätzlich solide ist und gezieltes Refactoring produktiv sein wird. Zwischen 8 und 14 brauchst du einen strukturierten Sanierungsplan mit konkreten Subsystemen oder Mustern, die systematisch Aufmerksamkeit brauchen. Unter 8 deuten die Daten auf einen teilweisen oder vollständigen Rewrite der betroffenen Bereiche hin.
Der Score ist der Ausgangspunkt für ein Gespräch, kein Urteil. Zwei Codebasen können denselben Score haben und trotzdem sehr unterschiedliche Antworten erfordern, je nach Teamkapazität, geschäftlichem Kontext und den Kosten der Veränderung.
Muster, die die Scorecard regelmäßig aufdeckt
Wendet man diese Scorecard auf verschiedene Codebasen an, tauchen einige Muster immer wieder auf.
Die brüchige Codebasis mit hoher Abdeckung: Die Testabdeckung sieht gut aus, aber der Mutation Score ist niedrig und die Change Failure Rate hoch. Die Tests prüfen Implementierungsdetails statt Verhalten. Refactoring ist hier oft die richtige Antwort, beginnt aber mit besseren Tests, bevor der Anwendungscode angefasst wird.
Die Falle aufgegebener Abhängigkeiten: Die Anwendungslogik ist vernünftig, aber der Abhängigkeitsbaum ist Jahre veraltet und voller bekannter CVEs. Das ist ein gut lösbares Problem, das schlimmer aussieht, als es ist. Ein Dependency-Audit und ein Upgrade-Sprint, kombiniert mit guter Testabdeckung, lösen es meist ohne architektonische Änderungen.
Der verfilzte Monolith: hohe Komplexität, starke Kopplung, geringe Testabdeckung und keine klaren Modulgrenzen. Das ist der wirklich harte Fall. Punktuelles Refactoring hat hier oft abnehmenden Ertrag, weil jede Änderungsfläche so groß ist. Die schrittweise Extraktion klar abgegrenzter Domänen - beginnend mit denen, die sich am häufigsten ändern - ist meist wirksamer als ein vollständiger Rewrite oder unfokussiertes Refactoring.
Aus der Scorecard ein Gespräch machen
Der eigentliche Wert der Scorecard ist nicht die Zahl, sondern dass sie das Gespräch mit nicht-technischen Stakeholdern präzise macht. Statt "der Code ist schwer zu warten" kannst du sagen: Unsere Change Failure Rate liegt bei 18 Prozent, die Testabdeckung der kritischen Pfade bei 34 Prozent, und wir haben drei kritische CVEs, die seit vier Monaten offen sind. Das ist ein anderes Gespräch.
Wenn du eine Codebasis im Rahmen von Code-Quality-Consulting, als technische Due Diligence vor einer Übernahme oder als Teil eines Legacy-Code-Modernisierungsprogramms bewertest, gibt dir diese Scorecard vor dem Zuschnitt der Arbeit eine Baseline, an der du Fortschritt misst, und eine klare Begründung, warum bestimmte Änderungen priorisiert werden.
Das Ergebnis sollte eine einseitige Zusammenfassung sein: Werte je Dimension, die zwei bis drei risikoreichsten Befunde und eine Empfehlung - Refactoring, teilweiser Rewrite bestimmter Subsysteme oder vollständiger Rewrite. Diese eine Seite macht die Entscheidung belastbar und verwandelt eine emotionale Debatte in ein Engineering-Problem.
Wie du anfängst
Wenn du deine Codebasis noch nie systematisch gemessen hast, ist das der schnellste Einstieg:
- Führe einen Komplexitätsscan mit einem Werkzeug passend zu deinem Stack durch. Markiere die 20 komplexesten Dateien.
- Zieh die Deployment-Daten der letzten 90 Tage und zähle Fehlschläge und Rollbacks.
- Führe ein Dependency-Audit durch und ermittle die CVE-Anzahl.
Diese drei Schritte kosten wenige Stunden und sagen dir mehr über den tatsächlichen Zustand deiner Codebasis als die meisten halbtägigen Workshops.
Wenn du eine strukturierte Bewertung mit Benchmarks gegen vergleichbare Systeme möchtest, melde dich unter hello@wolf-tech.io oder besuche wolf-tech.io. Wir haben diese Art von Review dutzendfach durchgeführt und liefern Scorecard und Empfehlung in der Regel innerhalb einer Woche schriftlich aus.
Eine Codebase-Health-Scorecard trifft die Entscheidung zwischen Refactoring und Rewrite nicht für dich. Aber sie liefert dir die Belege, um sie gut zu treffen, gegenüber Stakeholdern zu vertreten und zu prüfen, ob die Arbeit danach tatsächlich etwas bewegt.

