Wie misst man toten Code, ohne Geschäftsregeln zu löschen?
So lässt sich toter Code mit statischer Erreichbarkeit, Laufzeitabdeckung, Traffic-Replays und Tests für seltene Jahresendregeln messen.

Toter Code ist nicht alles, was alt, unbeholfen oder in der Produktion still wirkt. Es ist Code, über dessen Erreichbarkeit, Beobachtung und fachliche Verantwortung sich eine konkrete, belegte Aussage treffen lässt. Diese Aussagen sind verschieden. Wer sie unter einem einzigen Etikett zusammenfasst, entfernt bei einer Bereinigung oder Neuentwicklung schnell die einzige Implementierung einer jährlichen Anpassung, eines ruhenden Vertrags oder eines Wiederanlaufpfads.
Ich habe erlebt, wie Teams Routinen löschten, weil niemand ihren Namen kannte. Später stellte sich heraus, dass ein Scheduler sie am letzten Arbeitstag des Jahres unter einem Dienstkonto aufrief. Die Anwendung enthielt keinen eingehenden Aufruf, eine normale Traffic-Stichprobe zeigte keine Ausführung, und dennoch gab es genau einen echten Aufrufer. Eine brauchbare Messmethode muss diesen Fall abdecken.
Behandeln Sie vermuteten toten Code deshalb als Beweisfrage. Die statische Analyse zeigt, was aufgerufen werden kann. Die Laufzeitabdeckung zeichnet auf, was unter festgelegten Bedingungen aufgerufen wurde. Jobkataloge, Kalender, Konfiguration, Datenwerte, Betriebsanweisungen und Traffic-Archive legen Eingaben offen, die keine der beiden Methoden allein sieht. Gelöscht wird erst, wenn diese Unterlagen übereinstimmen, ein Verantwortlicher die Aussage akzeptiert und ein Paritätstest keinen Verhaltensverlust zeigt.
Toter Code hat drei verschiedene Bedeutungen
Ein Bericht über toten Code sollte unmögliche Pfade, nicht beobachtete Pfade und überholtes Verhalten getrennt ausweisen. Jede Kategorie rechtfertigt eine andere Maßnahme. Eine einzige Prozentzahl namens toter Code verbirgt genau die Unsicherheit, die Prüfer sehen müssen.
Statisch unerreichbarer Code hat unter dem Modell des Analysewerkzeugs von keinem deklarierten Einstiegspunkt einen möglichen Pfad. Eine nicht referenzierte private Funktion in einem geschlossenen Modul kann dazugehören. Das gilt auch für einen Zweig hinter einer Bedingung, die das Typsystem als falsch beweist. Dies ist das stärkste technische Signal, aber nur so vollständig wie die Liste der Einstiegspunkte und das Dispatch-Modell des Werkzeugs.
Zur Laufzeit nicht beobachteter Code erhielt während eines benannten Beobachtungsfensters und einer benannten Last keine Treffer. Diese Aussage sagt nichts über andere Daten, Mandanten, Rollen, Wertebereiche, Fehlerarten oder Bedienereingriffe. Die Abdeckung aus gewöhnlichem Web-Traffic verfehlt oft Batch-Jobs, Wiederanlaufbehandlung, Verwaltungsseiten, Migrationswerkzeuge und den Zweig für einen negativen Saldo nach einer Stornierung. Nennen Sie ihn nicht beobachtet, niemals unerreichbar.
Fachlich überholter Code läuft weiterhin oder bleibt erreichbar, doch das Unternehmen braucht sein Ergebnis nicht mehr. Eine Steuerregel für ein Land, das die Firma verlassen hat, könnte überholt sein. Eine Berechnung für ein eingestelltes Produkt muss es nicht sein, weil alte Konten noch Korrekturen brauchen. Nur ein fachlich Verantwortlicher kann diese Entscheidung anhand von Aufbewahrungspflichten und Vertragsdaten treffen. Ein Compiler kann das nicht.
Verwenden Sie ein Statusfeld statt eines booleschen Schalters:
- unerreichbar unter Modell M
- nicht beobachtet in Last W während Fenster T
- beibehalten für benanntes seltenes Ereignis E
- überholt durch Entscheidung D
- unbekannt, Untersuchung erforderlich
Dieses Vokabular verhindert einen stillen, häufigen Austausch. Ingenieure beginnen mit null Laufzeittreffern, sprechen in einer Sitzung von totem Code und genehmigen eine Löschung, als wäre die Unmöglichkeit bewiesen. Die Wörter haben sich geändert, die Belege nicht.
Statische Erreichbarkeit beweist Unmöglichkeit, nicht Nichtgebrauch
Die statische Erreichbarkeitsanalyse beweist am besten, dass der normale Kontrollfluss von bekannten Wurzeln aus kein Symbol erreicht. Am schwächsten ist sie, wenn ein Legacy-System Namen und Daten in Kontrollfluss umsetzt. Das Ergebnis muss seine Wurzeln, Auflösungsregeln und blinden Stellen immer mitführen.
Erfassen Sie zuerst jeden zulässigen Einstiegspunkt, nicht nur die Hauptanwendung. In einer Mainframe-Umgebung gehören dazu Transaktionsprogramme, Batch-Schritte in JCL, aufgerufene Module, Exits, Datenbanktrigger und vom Betrieb gestartete Hilfsprogramme. Auf einer AS/400 können CL-Programme und Jobbeschreibungen RPG-Programme aufrufen, die kein interaktiver Pfad erwähnt. Desktop-Systeme ergänzen COM-Einstiegspunkte, Berichtsmakros und über Dateizuordnungen geöffnete Dateien. Web-Monolithen bringen geplante Skripte, Queue-Consumer, Framework-Hooks und aus Konfiguration zusammengesetzte Routen mit.
Bauen Sie dann einen Aufrufgraphen, dessen Kanten eine Vertrauensstufe tragen. Ein vom Compiler aufgelöster Direktaufruf verdient eine stärkere Kennzeichnung als eine Zeichenfolge, die zufällig einem Prozedurnamen entspricht. Lassen Sie unaufgelöste indirekte Aufrufe sichtbar, statt sie zu verwerfen. Funktionszeiger, Reflection, Dependency Injection, späte Bindung, generiertes SQL, Namen gespeicherter Prozeduren und Plugin-Register erzeugen Kanten, die eine einfache Textsuche übersieht.
Garbage Collection des Linkers und die Entfernung toten Codes durch den Compiler beantworten eine engere Frage. Ihre Handbücher beschreiben das Entfernen von Abschnitten oder Anweisungen, die ein erzeugtes Programm bei einem bestimmten Build nicht beeinflussen können. Das hilft bei der Binärgröße. Es beweist nicht, dass eine Quellroutine über andere Build-Optionen, separat geladene Module, Skripte oder betriebliche Einstiegspunkte hinweg sicher entfernt werden kann. Eine optimierte Binärdatei als vollständiges Anwendungsmodell zu behandeln, verwechselt zwei Kategorien.
Ein kleines, prüfbares Erreichbarkeitsartefakt ist nützlicher als ein farbiger Graph mit zehntausend Knoten. Exportieren Sie pro Kandidat eine Zeile mit Symbol, Quellort, geprüften Wurzeln, eingehenden Direktaufrufen, möglichen indirekten Verweisen, Build-Varianten und Version des Analysewerkzeugs. Hängt eine Kante von einer Zeichenfolge, einem Konfigurationsschlüssel, einer Datenbankzeile oder einem Jobnamen ab, legen Sie diesen Beleg neben der Zeile ab.
Ein Kandidat verdient erst dann einen starken statischen Befund, wenn vier Fragen beantwortet sind: Welche Wurzeln wurden einbezogen? Welche Sprachen und generierten Artefakte wurden geparst? Wie wurden indirekte Aufrufe aufgelöst? Welche Komponenten liegen außerhalb des Repositorys? Ist eine Antwort unbekannt, bleibt der Befund vorläufig. Das ist keine übertriebene Vorsicht, sondern eine genaue Beschreibung des Modells.
Laufzeitabdeckung beweist Ausführung, nicht Sicherheit
Laufzeitabdeckung kann beweisen, dass Code in einer aufgezeichneten Last ausgeführt wurde. Null Treffer können nicht beweisen, dass der Code unnötig ist. Abdeckung bezeugt Anwesenheit, nicht Abwesenheit.
GNU gcov meldet, wie oft Zeilen und Zweige in einem instrumentierten Programm liefen. Coverage.py unterscheidet bei Python ähnlich und kann neben Anweisungen auch Zweigziele erfassen. Beide Handbücher beziehen die Ergebnisse auf die Programmläufe, die Sie bereitstellen. Diese Einschränkung ist wichtiger als die Prozentzahl: Ein Lauf prüft nur Eingaben, Umgebung, Daten, Identitäten und Fehler, die in diesem Lauf vorkamen.
Zeilenabdeckung verliert außerdem Details des Kontrollflusses. Eine Zeile mit einer zusammengesetzten Bedingung kann laufen, obwohl ein Operand seinen Wert nie ändert. Eine switch-Anweisung kann ausgeführt werden, während ein Fall unberührt bleibt. Zweigabdeckung verbessert die Belege, sagt aber noch nicht, ob die beobachtete Ausgabe korrekt war oder ein Nebeneffekt den richtigen Wert hatte. Sammeln Sie für Löschentscheidungen Zweig- oder Kantenabdeckung, wenn die Sprache dies zulässt, und kombinieren Sie sie mit einem Ausgabevergleich.
Instrumentieren Sie jede bei der statischen Analyse gefundene Ausführungsfläche. Interaktiver Traffic genügt selten. Erfassen Sie Batch-Programme, Queue-Worker, geplante Aufgaben, Berichtsgeneratoren, Datenbankroutinen, Wiederherstellungsbefehle und Verwaltungswerkzeuge. Führen Sie Abdeckungsdaten erst zusammen, nachdem Sie erklärende Dimensionen erhalten haben: Programmversion, Einstiegspunkt, Jobname, Mandant oder Geschäftsbereich, Rollenklasse, Datum und Lastquelle. Eine zusammengeführte Bitmap verschweigt, dass eine Zeile nur im jährlichen Abschlussjob lief.
Beobachtungsfenster sollten dem Geschäftskalender folgen und nicht einer bequemen Tageszahl. Berücksichtigen Sie tägliche, wöchentliche und monatliche Vorgänge sowie Quartalsende, Jahresende, Verlängerung, Ablauf, Zeitumstellung, Schalttag und behördliche Meldetermine, die das System tatsächlich verarbeitet. Wenn das Warten unpraktisch ist, spielen Sie eine aufgezeichnete Last erneut ab oder stellen das Ereignis in einer isolierten Umgebung nach. Drei arbeitsreiche Wochentage bilden kein Geschäftsjahr ab.
Abdeckungsinstrumentierung kann Timing, Speicherlayout und Fehlerverhalten verändern. Messen Sie den Overhead, besonders bei Race Conditions, Timeouts und Batch-Grenzen. Wo vollständige Instrumentierung unsicher ist, verwenden Sie Stichprobentraces, Aufrufzähler an stabilen Grenzen, Datenbank-Auditdaten oder vorhandene Jobprotokolle. Schwächere Belege sind in Ordnung, wenn sie ehrlich benannt und mit anderen Quellen kombiniert werden.
Zeit gehört zu den Eingaben
Seltener Kalendercode ist aktiver Code, dessen Eingabe ein Datum, ein Stichtag oder ein über eine Periode aufgebauter Zustand umfasst. Teams übersehen ihn, weil sie Zeit als Hintergrund statt als Eingabe des Programms behandeln.
Nehmen wir eine Zuteilungsroutine zum Jahresende. Die Online-Anwendung bucht das ganze Jahr normale Einträge. Am letzten Arbeitstag startet ein Scheduler nach dem Schließen des Hauptbuchs einen Batch-Job. JCL übergibt einen Modusschalter, eine Steuertabelle bezeichnet Konten mit abgegrenzten Salden, und das Programm erzeugt Ausgleichsbuchungen für die nächste Periode. Keine Webanfrage ruft die Routine auf. Kein Entwickler erkennt ihren abgekürzten Namen. Elf Monate Produktionsabdeckung zeigen null Treffer.
Eine Neuentwicklung löscht die Routine und ersetzt den umgebenden Ledger-Dienst. Gewöhnliche Paritätstests bestehen, weil ihre Testdaten Termine im März und Juni verwenden. Zum Jahresende bleiben die Summen intern ausgeglichen, daher bestehen auch einfache Buchhaltungsprüfungen. Der Fehler zeigt sich später, wenn Auszüge von der vertraglichen Zuteilungsregel abweichen. Die verlorene Geschäftsregel war kein spektakulärer Zweig. Sie bestand aus der geplanten Kombination von Datum, Jobsteuerung, Tabellenzustand und Ausgabeperiode.
Erstellen Sie neben dem Aufrufgraphen ein Ereignisinventar, um solchen Code zu finden. Fragen Sie Finanzbereich, Betrieb, Support und Compliance nach benannten Ereignissen, aber verlassen Sie sich nicht nur auf Erinnerungen. Prüfen Sie Scheduler-Definitionen, JCL, Cron-Tabellen, Jobverlauf, Betriebsanweisungen, Steuertabellen, Berichtskalender, Muster eingehender Dateien und Zeitstempel von Archiven. Suchen Sie nach Datumsvergleichen, Periodennummern, Feiertagskalendern, speziellen Verarbeitungsschaltern und Konstanten, die wie alte Stichtagsjahre aussehen.
Halten Sie die letzte beobachtete Ausführung und die nächste erwartete Gelegenheit fest. Eine Routine, die zuletzt am vergangenen Jahresende lief, hat eine klare Erklärung. Eine Routine ohne Treffer seit vier Jahren kann noch ein fünfjähriges Korrekturfenster abdecken. Umgekehrt kann ein nächtlicher Job einen Zweig nur dann aufrufen, wenn eine Steuerzeile vorhanden ist. Die Häufigkeit des Aufrufers belegt nicht die Häufigkeit jeder Regel in ihm.
Die Ersetzung der Uhr verdient eine eigene Testschnittstelle. Leiten Sie die Anwendungszeit möglichst über eine kontrollierbare Quelle und frieren Sie Datenbank- oder Schedulerzeit in der Testumgebung konsistent ein. Liest eine Komponente ein simuliertes Datum und eine andere die Host-Uhr, kann der Test beruhigende, aber unmögliche Zustände erzeugen.
Vor jeder Löschung steht ein Beweisregister
Ein Beweisregister macht aus einer vagen Debatte über toten Code eine Menge von Aussagen, die ein anderer Ingenieur reproduzieren kann. Es sollte bei der Migration oder Bereinigung liegen, wie Code geprüft werden und die Rohverweise hinter jeder Schlussfolgerung erhalten.
Eine Zeile pro Symbol oder zusammenhängender Funktion reicht. Sinnvolle Felder sind Kandidaten-ID, Quellsymbol, statischer Status, statische Wurzeln, unaufgelöste Kanten, Laufzeittreffer, Beobachtungsfenster, enthaltene Lasten, Kennzeichen für seltene Ereignisse, externe Aufrufer, fachlich Verantwortlicher, Entscheidung und Belegorte. Wandeln Sie unbekannte Werte nicht in null um. Null bedeutet gemessen und abwesend; unbekannt bedeutet nicht gemessen.
Ein Abdeckungsspeicher kann mit einer gewöhnlichen Abfrage eine brauchbare Kandidatenliste erzeugen. Passen Sie die Namen an Ihr Schema an, aber behalten Sie die Gruppierungsdimensionen bei:
SELECT s.symbol_id, s.qualified_name,
COALESCE(SUM(c.hit_count), 0) AS hits,
MIN(c.observed_at) AS first_seen,
MAX(c.observed_at) AS last_seen,
COUNT(DISTINCT c.workload_id) AS workloads
FROM symbols s
LEFT JOIN coverage_events c ON c.symbol_id = s.symbol_id
WHERE s.release_id = :release_id
GROUP BY s.symbol_id, s.qualified_name
ORDER BY hits, s.qualified_name;
Die Ausgabe sollte nüchtern und prüfbar sein: ein Symbol, seine Gesamttreffer, erste und letzte Beobachtung sowie die Zahl verschiedener Lasten. Verknüpfen Sie sie mit einer Lasttabelle, die Online-Traffic, Monatsende, Jahresende, Wiederherstellung, Verwaltung oder Replay kennzeichnet. Eine Null in einem Datensatz mit ausschließlich Online-Traffic macht ein Batch-Symbol nicht zum Löschkandidaten.
Ergänzen Sie die Prüfung um eine kompakte Entscheidungstabelle:
| Statisches Ergebnis | Laufzeitergebnis | Fachlicher Beleg | Maßnahme |
|---|---|---|---|
| Unerreichbar | Keine Treffer | Kein externer Einstieg | Isolieren, dann Löschung testen |
| Erreichbar | Keine Treffer | Seltenes Ereignis vorhanden | Behalten und gezielt testen |
| Erreichbar | Treffer | Verantwortlicher nennt es überholt | Aufrufer bestätigen, dann Verhalten stilllegen |
| Unbekannt | Keine Treffer | Unbekannt | Untersuchen, nicht löschen |
Die erste Zeile verlangt weiterhin einen Build- und Verhaltenstest. Generierter Code, alternative Builds und Paketierung können einen scheinbar geschlossenen Graphen ungültig machen. Auch die dritte Zeile braucht Sorgfalt: Beobachtete Aufrufer können Nebeneffekte benötigen, obwohl die offizielle Fachfunktion beendet ist. Entfernen Sie Aufrufpfad und Datenpflichten gemeinsam, statt einen kaputten Teilpfad zurückzulassen.
Seltene Pfade werden gezielt ausgeführt
Ein seltener Pfad braucht eine gezielte Last und nicht die Hoffnung, dass die Produktion ihn irgendwann abdeckt. Leiten Sie Tests aus dem Ereignisinventar ab und definieren Sie die erwarteten Ausgaben so genau, dass eine fehlende Regel auffällt.
Aufgezeichneter Produktionstraffic ist nützlich, weil er Kombinationen bewahrt, die künstliche Testdaten selten vorwegnehmen. Bereinigen oder tokenisieren Sie sensible Felder nach den Anforderungen der Umgebung, erhalten Sie bei zustandsabhängigen Abläufen die Reihenfolge und erfassen Sie Begleitzustand wie Steuertabellen, Uhrwerte und Dateien. Eine Anfrage ohne Datenbankzustand ist oft keine reproduzierbare Last. Archivieren Sie bei Batch-Systemen Jobeingaben, Parameter, Returncodes, erzeugte Dateien, Datenbankänderungen und Bedienermeldungen.
Fügen Sie künstliche Grenzfälle hinzu. Verwenden Sie den Tag vor dem Stichtag, den Ereignistag und den Tag danach. Testen Sie leere Eingaben, das kleinste gültige Konto, eine negative Buchung oder Stornierung, ein spät in der Periode angelegtes Konto und einen Wiederanlauf nach teilweiser Verarbeitung. Das sind keine zufälligen Randfälle. Sie prüfen Auswahl, Berechnung, Speicherung und Wiederherstellung getrennt.
Vergleichen Sie das Verhalten an beobachtbaren Grenzen. HTTP-Antworten zählen, ebenso Datenbankschreibvorgänge, Dateisätze, Nachrichten, Exitcodes, Rundung, Reihenfolge und Zeitfenster für Wiederholungen. Normalisieren Sie bewusst nichtdeterministische Werte wie erzeugte IDs, halten Sie Fachwerte aber exakt. Schreibt das alte System einen Datensatz fester Breite, vergleichen Sie Feldpositionen und Auffüllung ebenso wie geparste Werte, denn ein nachgelagerter Verbraucher kann von den Bytes abhängen.
Verfolgen Sie keine einzelne Abdeckungsprozentzahl als Ziel. Eine Suite kann hohe Zeilenabdeckung erreichen und trotzdem den Zweig für Fiskalperiode 13 verfehlen. Ordnen Sie stattdessen jeden Kandidaten einer Last zu, die ihn erreichen sollte, oder beweisen Sie, warum keine Last ihn erreichen kann. Die nützliche Einheit ist ein erklärtes Symbol, nicht eine farbige Zeile.
Wenn sich ein Pfad nicht sicher ausführen lässt, erstellen Sie darunter einen Charakterisierungstest. Rufen Sie die Berechnung mit aufgezeichneten Eingaben auf, führen Sie die gespeicherte Prozedur in einer wiederhergestellten Datenbank aus oder starten Sie das Batch-Modul mit seinem echten Parameterblock. Dokumentieren Sie, was an der Integrationsgrenze ungetestet bleibt. Eine genaue Lücke lädt zur Prüfung ein; eine gerundete Prozentzahl verbirgt sie.
Die Löschung läuft als kontrolliertes Experiment
Löschen Sie vermuteten Code in kleinen, umkehrbaren Einheiten und lassen Sie das System Ihre Behauptung widerlegen. Der beste Löschtest entfernt den Kandidaten, baut jede Variante neu, spielt die Lastmenge ab und vergleicht alle beobachtbaren Auswirkungen mit der Basislinie.
Beginnen Sie bei verworrenen Abhängigkeiten mit Isolation. Setzen Sie eine einzelne Schnittstelle vor den Kandidaten, entfernen Sie doppelte Einstiegspunkte und ergänzen Sie dort Protokollierung oder Zähler. Das ändert die Struktur ohne Verhaltensänderung und schafft einen sauberen Messpunkt. Sieht die Schnittstelle über die nötige Ereignismenge keine Aufrufe, ist die spätere Löschung besser belegt.
Bewahren Sie für jede Löschung vier Artefakte: den Eintrag im Beweisregister, den genauen Quelldiff, Basislinienausgaben und Ausgaben nach dem Entfernen. Führen Sie Unit- und Integrationstests aus, kompilieren Sie alternative Ziele, starten Sie Batch- und Verwaltungslasten und spielen Sie aufgezeichneten Traffic ab. Prüfen Sie Datenbankänderungen und ausgegebene Dateien, nicht nur den Prozesserfolg. Ein erfolgreicher Returncode kann neben einer fehlenden Buchung stehen.
Ein Schattenvergleich hilft, wenn eine Berechnung ohne Nebeneffekte laufen kann. Führen Sie alte und neue Logik mit derselben aufgezeichneten Eingabe aus, unterdrücken Sie die Schreibvorgänge einer Seite und vergleichen Sie normalisierte Ergebnisse. Spiegeln Sie keine Vorgänge, die belasten, benachrichtigen, Bestand reservieren oder gemeinsamen Zustand ändern, sofern die Architektur kein sicheres Ziel bietet. Doppelte Nebeneffekte verursachen sonst den Vorfall, den der Test verhindern soll.
Die verbreitete Empfehlung, alles mit null Treffern nach einer festen Beobachtungszeit zu löschen, ist attraktiv, weil sie einen sauberen Rückstand und eine einfache Kennzahl erzeugt. Für Systeme mit Kalenderereignissen, ruhenden Verträgen, manueller Wiederherstellung oder datengesteuertem Dispatch ist sie falsch. Legen Sie die Anforderungen je Funktionsklasse fest: Eine Online-Validierung braucht repräsentativen Traffic über Rollen und Mandanten, eine Abschlussroutine mindestens eine originalgetreue Abschlusslast.
Halten Sie die Rücknahme praktisch möglich. Ein Revert im Quellverwaltungssystem reicht nicht, wenn die Löschung auch Datenformen ändert, eine Spalte entfernt, eine Datei nicht mehr befüllt oder Nachrichtenverträge verändert. Verschieben Sie destruktive Schemaänderungen hinter die Stilllegung des Verhaltens und behalten Sie einen Kompatibilitätspfad, bis die nachgelagerten Belege nachziehen. Umkehrbare Arbeit verbessert die Beweislage, ohne aus jedem unsicheren Befund eine endlose Sitzung zu machen.
Eine Neuentwicklung erhält erst Verhalten und verbessert dann den Entwurf
Eine Neuentwicklung sollte altes Verhalten klassifizieren und testen, bevor sie entscheidet, welcher alte Code neu implementiert wird. Jede erreichbare Routine zu übersetzen erhält zufällige Struktur. Jede verdächtige Routine zu löschen verliert Regeln. Ziel ist Verhaltensparität für bestehende Pflichten, danach folgt die bewusste Architekturänderung.
Bauen Sie den Paritätstest um Produktionsbeobachtungen und benannte seltene Ereignisse. Geben Sie altem und neuem System dieselben geordneten Eingaben und denselben Anfangszustand. Vergleichen Sie Antworten, dauerhaften Zustand, Dateien, Nachrichten und Fehlerverhalten. Ändert die Architektur die Form einer Schnittstelle, vergleichen Sie eine kanonische fachliche Darstellung, statt das neue System intern zur Nachbildung alter Module zu zwingen.
Hier zahlt sich die Trennung von Codeparität und Verhaltensparität aus. Ein neuer Go-Dienst braucht weder die Absatzgrenzen eines COBOL-Programms noch die globalen Variablen eines VB6-Formulars. Er braucht bis zur genehmigten Regeländerung dieselben Zuteilungsbeträge, Berechtigungsentscheidungen, Rundungsregeln und Wiederherstellungsgarantien. CodeHero nutzt aufgezeichneten Produktionstraffic in einem Paritätstest und modernisiert zugleich die Architektur, genau auf dieser Ebene muss der Vergleich für dieses Problem stattfinden.
Geben Sie entferntem Verhalten eine benannte negative Assertion. Soll ein überholter Bericht verschwinden, testen Sie, dass kein Job ihn plant und keine Datei erzeugt wird. Soll eine alte Produktregel nicht mehr gelten, fügen Sie einen früher berechtigten Datensatz ein und prüfen die neu genehmigte Behandlung. Abwesenheit wird testbar, wenn Sie die Grenze definieren, an der der Effekt erschienen wäre.
Lassen Sie den neuen Entwurf die Herkunft nicht auslöschen. Verknüpfen Sie jede implementierte Regel, jede bewusst geänderte Regel und jeden ausgelassenen Kandidaten mit Belegen im Register. Prüfer sollten fragen können, warum im Ziel ein Zweig existiert, und dessen Last, Verantwortlichen und erwartete Wirkung finden. Ebenso müssen sie erkennen können, warum eine Quellroutine verschwand, und mehr als einen Kommentar mit dem Wort unbenutzt finden.
Legen Sie eine prüfbare Löschregel fest
Eine Löschrichtlinie funktioniert nur, wenn sie Belege, Befugnis und eine Abbruchbedingung festlegt. Formulieren Sie sie so, dass ein Prüfer eine Änderung ablehnen kann, ohne darüber zu streiten, ob der Code alt wirkt.
Ein vertretbares Gate kann alle folgenden Punkte verlangen:
- Die statische Analyse fand keinen ungeklärten eingehenden Pfad aus dem vollständigen Einstiegspunktinventar, oder alle verbliebenen Aufrufer gehören zur Stilllegung.
- Die Laufzeitbelege deckten die relevanten Lastklassen und Kalenderereignisse des Kandidaten ab, die Rohdaten bleiben erhalten.
- Externe Aufrufer, Konfigurationsverweise, Scheduler-Einträge, datengesteuerter Dispatch und Betriebsanweisungen wurden geprüft.
- Ein benannter Verantwortlicher genehmigte die fachliche Überholung, oder technische Belege bewiesen den Pfad ohne fachliches Urteil als unmöglich.
- Die Entfernung bestand Builds, gezielte Tests, Traffic-Replay und den Vergleich dauerhafter Nebeneffekte, einschließlich Rücknahmeplan für abhängige Daten und Verträge.
Das Gate sollte ein ausdrückliches Ergebnis unbekannt zulassen. Manche Routinen lassen sich erst einordnen, nachdem ein Archiv wiederhergestellt oder ein Abschlussereignis rekonstruiert wurde. Sie als unbekannt zu markieren ist Fortschritt, denn damit steht der fehlende Beleg fest. Sie zur Verbesserung einer Prozentzahl zu löschen ist kein Fortschritt.
Messen Sie die Arbeit mit Anzahlen je Beweisstatus: untersuchte Kandidaten, als unerreichbar bewiesene Pfade, seltene Pfade mit Tests, genehmigte überholte Verhaltensweisen, verbleibende Unbekannte und Löschungen mit bestandener Parität. Belohnen Sie keine rohe Zeilenzahl. Eine zehnzeilige Jahresendregel kann mehr Pflichten tragen als zehntausend Zeilen aufgegebener Bildschirmcode.
Nehmen Sie zuerst eine angeblich tote Routine und schreiben Sie die genaue Behauptung auf. Lautet sie nur, dass niemand sie je laufen sah, haben Sie Vertrautheit gemessen und nicht toten Code. Ergänzen Sie Wurzeln, Lasten, Kalenderereignisse, Verantwortliche und beobachtbare Wirkungen, bis ein anderer Ingenieur das Ergebnis reproduzieren kann. Erst dann gehört die Löschtaste in den Prozess.
FAQ
Was unterscheidet toten von unbenutztem Code?
Für toten Code ist belegt, dass keine notwendige Ausführung ihn erreichen oder brauchen kann. Unbenutzt bedeutet oft nur, dass ein Werkzeug oder Beobachtungsfenster keine Nutzung fand, obwohl externe Aufrufer und seltene Ereignisse weiter existieren können.
Kann statische Analyse beweisen, dass Code tot ist?
Sie kann Unerreichbarkeit innerhalb eines festgelegten Modells aus Wurzeln und Dispatch beweisen. Reflection, generierte Aufrufe, Konfiguration, Scheduler, Datenbanktrigger oder Komponenten außerhalb des Repositorys schwächen den Beweis.
Machen null Laufzeittreffer eine Funktion sicher löschbar?
Nein. Null Treffer bedeuten nur, dass die Funktion in den gemessenen Lasten und Zeiträumen nicht lief. Vor der Löschung brauchen Sie statische Erreichbarkeit, seltene Ereignisse, die Prüfung externer Aufrufer und eine fachliche Entscheidung.
Wie lange sollte Abdeckung laufen, bevor Code als tot gilt?
Folgen Sie dem Geschäftskalender statt einer festen Dauer. Fenster oder Replay müssen relevante tägliche Jobs, Periodenabschlüsse, Verlängerungen, Ablaufereignisse, Wiederherstellungsabläufe und jährliche Verarbeitung enthalten.
Wie findet man Code, der nur am Jahresende läuft?
Prüfen Sie Scheduler-Verlauf, JCL oder Jobdefinitionen, Betriebsanweisungen, Steuertabellen, Archivzeitstempel und Datumsbedingungen. Stellen Sie den Abschluss mit echten Parametern und Zustand nach und erfassen Sie Zweigabdeckung sowie Ausgaben.
Zählt vom Compiler entfernter Code als toter Quellcode?
Nicht automatisch. Ein Compiler beweist nur, was ein Build aus einem erzeugten Programm weglassen kann. Andere Build-Optionen, geladene Module, Skripte und betriebliche Einstiegspunkte können den Quellcode weiter benötigen.
Was gehört in ein Beweisregister für toten Code?
Erfassen Sie Symbol, geprüfte Einstiegspunkte, unaufgelöste Kanten, Laufzeitlasten, Beobachtungsdaten, seltene Ereignisse, externe Verweise, Verantwortlichen, Entscheidung und Rohbelege. Halten Sie unbekannt von null getrennt.
Wie testet man die Löschung von Legacy-Code?
Erfassen Sie Basislinienausgaben, entfernen Sie einen kleinen Kandidaten, bauen Sie alle wichtigen Varianten und spielen Sie gezielte Lasten ab. Vergleichen Sie dauerhaften Zustand, Dateien, Nachrichten, Exitcodes und Fehlerverhalten, nicht nur API-Antworten.
Reicht eine hohe Codeabdeckung für eine Neuentwicklung?
Nein. Ein hoher Gesamtwert kann einen einzelnen Fiskalzweig oder Wiederanlaufpfad verfehlen. Ordnen Sie erhaltenes Verhalten benannten Lasten zu und vergleichen Sie alte und neue Wirkungen an fachlichen Grenzen.
Wer sollte die Entfernung einer alten Geschäftsregel genehmigen?
Ein benannter fachlich Verantwortlicher sollte anhand technischer Belege zu Aufrufern und Wirkungen bestätigen, dass die Pflicht überholt ist. Ingenieure können einen Pfad als unmöglich beweisen, sollten Vertrags- oder Richtlinienänderungen aber nicht aus Schweigen ableiten.