Was gehört in eine Schätzung für ein Software-Rewrite?
Eine Schätzung für ein Software-Rewrite sollte Codeumfang, Verzweigungen, Integrationen, Daten, Betrieb und Testoberfläche mit Nachweisen messen.

Eine Schätzung für ein Rewrite sollte die Unsicherheit im Verhalten beschreiben und nicht denjenigen belohnen, der das Repository am schnellsten gezählt hat. Codezeilen spielen eine Rolle, weil jemand sie prüfen und ersetzen muss, doch der Zeilenumfang ist nur eine Eingabe. Verzweigungstiefe, externe Integrationen, Datensemantik, betriebliche Jobs und die für Paritätstests verfügbare Oberfläche beeinflussen die Schätzung oft stärker als die reine Größe.
Ich habe erlebt, dass kompakte Abrechnungssysteme länger für den Ersatz brauchten als ausufernde Reporting-Anwendungen. Das kleine System verbarg Regeln in verschachtelten Zweigen, speicherte Zwischenzustände in Tabellen, die niemand dokumentiert hatte, und rief Dienste auf, die sich zum Monatsende anders verhielten. Das größere wiederholte einfache CRUD-Muster und hatte saubere Request-Logs. Jede Schätzung, die bei "300.000 Zeilen" beginnt und endet, klebt ein präzises Etikett auf einen nicht vermessenen Auftrag.
Was die Zeilenzahl aussagen kann
Die Zeilenzahl ist ein nützliches Maß für den Prüfungsumfang, misst aber nicht allein die Schwierigkeit eines Rewrites. Ein Team braucht trotzdem eine reproduzierbare Zählung, weil in Verkaufsgesprächen oft Repository-Größe, Dateianzahl und ausführbare Zeilen miteinander vermischt werden.
Legen Sie die Zählregel fest, bevor Sie Angebote vergleichen. Trennen Sie mindestens produktiven Quellcode, generierten Code, eingebundene Abhängigkeiten, Tests, Datenbankcode, Jobsteuerung, Konfiguration und Kommentare. Eine Million Zeilen inklusive generierter Client-Stubs sind ein anderes System als eine Million handgeschriebene Zeilen COBOL, JCL, SQL und Copybooks. Wenn ein Anbieter diese Kategorien nicht zeigen will, lässt sich die Summe nicht prüfen.
Ein einfacher Inventurbefehl gibt technischen Leitern eine erste Kontrollmöglichkeit. cloc ist kein Schätzwerkzeug, liefert aber eine stabile Struktur, die sich nach geänderten Ausschlüssen erneut erzeugen lässt:
cloc . --exclude-dir=vendor,node_modules,dist --by-file --json --out=cloc.json
jq '.SUM | {blank, comment, code}' cloc.json
Das Ergebnis hat diese Form:
{"blank":18420,"comment":27116,"code":263904}
Bewahren Sie auch die Ausgabe auf Dateiebene auf. Damit kann ein Prüfer konzentrierte Subsysteme, generierte Blöcke außerhalb der Ausschlüsse und beim ersten Durchlauf übersehene Sprachen finden. Bei einer Mainframe-Landschaft müssen JCL, Copybooks, Assembler-Exits, SQL-Prozeduren, Screen-Maps und Scheduler-Definitionen neben der Anwendungssprache gezählt werden. Sie enthalten vielleicht wenig Geschäftslogik, bestimmen aber, wie das System startet, stoppt, Dateien austauscht und sich erholt.
Die Zeilenzahl eignet sich am besten als Nenner. Fehler pro tausend Zeilen, Zweige pro Modul, Integrationsaufrufe pro tausend Zeilen und Tests für jede Geschäftsfähigkeit sagen jeweils etwas aus. Ein Preis, der durch Multiplikation der Zeilen mit einem universellen Satz entsteht, tut das nicht. Dieselbe Zeile kann eine Felddeklaration, ein generierter Getter oder der Zweig sein, der entscheidet, ob ein Konto nach einer rückdatierten Anpassung Zinsen erhält.
Verzweigungen messen das zu erhaltende Verhalten
Verzweigungen sind wichtig, weil jeder Entscheidungspfad ein eigenes beobachtbares Verhalten codieren kann. Zählen Sie Entscheidungspunkte, messen Sie ihre Kombination und bestimmen Sie, wo Zustand oder externe Daten das Ergebnis verändern. Ein flaches Modul mit zwanzig unabhängigen Prüfungen ist leichter zu verstehen als eine Routine, in der zehn Entscheidungen ineinander verschachtelt sind und gemeinsamen veränderlichen Zustand nutzen.
Die zyklomatische Komplexität ist ein brauchbares erstes Signal. Thomas McCabe definierte sie anhand des Kontrollflussgraphen, für eine verbundene Routine häufig als Anzahl der Entscheidungen plus eins zusammengefasst. Der Wert sagt den Aufwand nicht allein voraus. Er zeigt, wie viele unabhängige Pfade existieren, während die Verschachtelung zeigt, wie schwer Menschen oder Werkzeuge diesen Pfaden folgen können.
Der Unterschied zwischen Zweigzahl und Verzweigungstiefe wird regelmäßig verwischt. Nehmen wir zwei Routinen mit jeweils acht Entscheidungen. In der ersten weisen acht Guard Clauses ungültige Datensätze ab, danach läuft eine Berechnung. In der zweiten sind Berechtigung, Rechtsraum, Produktklasse, Gültigkeitsdatum, Ausnahmestatus und frühere Anpassungen sechs Ebenen tief verschachtelt. Beide können einen ähnlichen zyklomatischen Wert erhalten. Die zweite braucht meist mehr Fixtures, eine sorgfältigere Rekonstruktion des Zustands und mehr Prüfung, weil eine Bedingung die Bedeutung aller darunterliegenden Bedingungen verändert.
Verlangen Sie von einem Anbieter eine Verteilung statt eines Durchschnitts. Ein Mittelwert über das Repository verbirgt die fünf Routinen, die Geldbewegungen oder den Anlagenbetrieb steuern. Nützliche Gruppen sind Routinen oberhalb eines vereinbarten zyklomatischen Grenzwerts, maximale Verschachtelungstiefe, Fan-in, Fan-out und die Menge des Codes, die von folgenreichen Einstiegspunkten erreichbar ist. Der Grenzwert soll Prüfaufwand markieren und Code nicht pauschal als "schlecht" bezeichnen.
Fragen Sie auch, ob die Analyse dynamischen Dispatch, generierte Aufrufe, Makros und datenbankgesteuerte Regeln auflöst. Statische Analyse kann einen aus einer Tabelle gelesenen Programmnamen, einen zur Laufzeit zusammengesetzten COBOL-CALL oder ein VB6-Formularereignis außerhalb der sichtbaren Routine übersehen. Ein ehrlicher Bericht kennzeichnet nicht aufgelöste Kanten. Fehlende Graphdaten werden nicht stillschweigend als geringe Komplexität gewertet.
Komplexität verändert eine Schätzung durch den Aufwand für Nachweise. Jeder folgenreiche Pfad braucht eine bekannte Eingabe, eine erwartete Ausgabe und den passenden Anfangszustand. Wenn Produktionstraces die meisten Pfade abdecken, kann das Team Fälle aus der Realität ableiten. Wenn Logs nur einen abschließenden Statuscode erfassen, muss jemand die Entscheidungen durch Quellcodeprüfung und gezielte Läufe rekonstruieren. Obwohl der Code gleich ist, unterscheidet sich der Aufwand deutlich.
Externe Integrationen erzeugen Risiken an Grenzen
Externe Integrationen brauchen ein eigenes Inventar, weil Rewrites häufiger an Grenzen als an Syntax scheitern. Eine "Integration" ist mehr als eine HTTP-API. Dazu gehören Dateien auf gemeinsamem Speicher, Message Queues, Terminalsitzungen, Datenbank-Links, Druckerströme, SMTP, Scheduler-Ereignisse, Shell-Befehle, Identitätsanbieter, Hardwaregeräte und Menschen, die Ausgaben manuell zwischen Systemen verschieben.
Zählen Sie jeden eigenständigen Vertrag und erfassen Sie Richtung, Protokoll, Eigentümer, Häufigkeit, Authentifizierung, Datenform, Fehlerverhalten und Testersatz. Zehn Endpunkte hinter einem dokumentierten Service-Client können einfacher sein als eine einzige nächtliche Datei mit fester Breite, deren Eigentümer gegangen ist und deren abgewiesene Datensätze in einem Operator-Postfach erscheinen.
Die unangenehme Frage lautet, ob sich eine Integration außerhalb der Produktion ausführen lässt. Eine Anbieter-Sandbox mit künstlichen Daten bildet Drosselung, Reihenfolge, Zertifikatswechsel oder Tagesabschluss womöglich nicht nach. Für eine gemeinsam genutzte Datenbank existiert vielleicht keine Testkopie. Ein Partner erlaubt eventuell nur ein einziges Zertifizierungsfenster. Diese Einschränkungen gehören in die Schätzung, weil sie bestimmen, wie schnell das Team die Korrektheit des Ersatzsystems prüfen kann.
Inventarisieren Sie beide Seiten jeder Grenze. Der Aufruf einer API ist nur die Hälfte des Vertrags. Das Altsystem wiederholt möglicherweise bei bestimmten Codes, unterdrückt Duplikate, verlässt sich auf die Reihenfolge der Antworten oder schreibt nach einem Timeout einen Abstimmungsdatensatz. Dateischnittstellen tragen vergleichbare Regeln in Benennung, Codierung, Zeilenenden, Trailern, leeren Dateien, Teillieferungen und Wiederholungen. Wer all das als "eine SFTP-Integration" behandelt, verwirft genau die Details, die den Umstieg am ehesten stoppen.
Verantwortung ist eine Eingabe für den Zeitplan und keine organisatorische Fußnote. Halten Sie fest, wer Fragen beantworten, Zugangsdaten ausstellen, eine Firewall-Regel genehmigen, ein Beispiel liefern und einen Test beobachten kann. Fehlt ein Eigentümer, müssen Discovery und Reserve ausdrücklich bepreist werden. Verstecken Sie dieses Risiko nicht in einem allgemeinen Projektpuffer, denn Leiter brauchen die Möglichkeit, vor der Unterschrift jemanden zu benennen.
Eine glaubwürdige Schätzung trennt die Implementierung einer Integration vom Nachweis der Integration. Einen neuen Client zu schreiben kann Routine sein. Zu beweisen, dass er bei Wiederholungen, ungültigen Eingaben, Duplikaten, verspäteter Lieferung und Ausfall des Partners richtig reagiert, enthält die Unsicherheit. Fragen Sie nach beiden Zahlen.
Die Testoberfläche bestimmt das Vertrauensniveau
Die Testoberfläche umfasst die beobachtbaren Verhaltensweisen, die sich anstoßen und vergleichen lassen, nicht die Zahl der Testdateien im Repository. Vorhandene Unit-Tests helfen nur, wenn sie Verhalten prüfen, das das neue System erhalten muss. Eine Suite voller Mocks kann die alte Klassenstruktur beschreiben und wenig über Rechnungen, Buchungen, Nachrichten oder Dateien an der Systemgrenze aussagen.
Messen Sie die Oberfläche nach Geschäftsfähigkeit und Beobachtungspunkt. Erfassen Sie für jeden Einstiegspunkt, welche Eingaben erneut abgespielt, welche Anfangszustände wiederhergestellt, welche Ausgaben erfasst und welche Nebeneffekte verglichen werden können. Dazu gehören API-Antworten, Datenbankänderungen, ausgehende Nachrichten, erzeugte Dateien, Ledger-Einträge, Berechtigungen, für die Reihenfolge relevante Zeitabläufe und für Operatoren sichtbare Fehler.
Aufgezeichneter Produktionsverkehr ist besonders nützlich, weil er Kombinationen enthält, an die im Testplan niemand gedacht hat. Er braucht trotzdem Regeln für den Umgang. Geheimnisse und personenbezogene Daten können eine Schwärzung verlangen, Requests hängen vielleicht von abgelaufenem Zustand ab, und das erneute Abspielen eines Befehls kann einen externen Nebeneffekt auslösen. Ein Trace ist ein Nachweis, aber nicht automatisch ein sicheres Fixture.
Abdeckung hat bei einem Rewrite mindestens drei Bedeutungen, und Angebote tauschen sie oft ohne Hinweis aus. Quellcodeabdeckung fragt, welche alten Anweisungen oder Zweige ausgeführt wurden. Anforderungsabdeckung fragt, welche dokumentierten Regeln Tests besitzen. Verhaltensabdeckung fragt, welche von außen sichtbaren Kombinationen aus Eingabe und Ausgabe verglichen wurden. Ein Rewrite kann hohe Quellcodeabdeckung melden und dennoch eine undokumentierte Dateikonvention verpassen, von der der Betrieb abhängt. Für die Abnahme wiegt die Verhaltensabdeckung am stärksten.
Fragen Sie, wie Abweichungen klassifiziert werden. Manche Unterschiede sind Fehler. Manche legen einen alten Fehler offen, den das Unternehmen vorübergehend erhalten will. Andere entstehen durch Zeitstempel, generierte Kennungen, Reihenfolge, Rundung, Gebietsschema oder nichtdeterministische Abhängigkeiten und müssen normalisiert werden. Ohne vereinbarte Vergleichsregeln ist eine Paritätsquote bedeutungslos, weil ein Team sie durch Ignorieren schwieriger Felder verbessern kann.
Die Schätzung muss das vorgesehene Nachweisniveau nennen. Ein internes Nachschlagewerkzeug mit geringen Folgen kommt vielleicht mit repräsentativen Fällen und Nutzerabnahme aus. Eine Buchungsmaschine kann Replay aufgezeichneten Verkehrs, auf Zweige gerichtete Fixtures, Abstimmungssummen und kontrollierte Fehlerinjektion verlangen. Das gewünschte Vertrauen verändert die Arbeit. "Denselben Code neu schreiben" legt dieses Ziel nicht fest.
Datensemantik kann die Anwendungsgröße überwiegen
Datenarbeit wächst mit Bedeutung, Historie und Kopplung, nicht nur mit der Zahl der Zeilen. Eine kleine Datenbank kann überladene Spalten, implizite Codes, kaputte Fremdschlüssel, zeitliche Regeln und Stored Procedures enthalten, die den Großteil des Systemverhaltens tragen. Eine große, nur ergänzte Ereignistabelle lässt sich womöglich sauber verschieben, weil ihr Vertrag einfach ist.
Schätzen Sie Schemaübersetzung, Datenbereinigung, Ausführung der Migration, Abstimmung und Rollback getrennt. Das sind verschiedene Aufgaben. Ein Packed-Decimal-Feld in einen numerischen Postgres-Typ zu übersetzen ist mechanisch. Ob leer, null und ein Sentinel-Wert alle "unbekannt" bedeuten, verlangt Nachweise aus Code und Produktionsdaten. Die Abstimmung beweist anschließend, dass die gewählte Zuordnung Salden und Anzahlen erhalten hat.
Verborgener Zustand ist besonders teuer. Legacy-Programme kommunizieren häufig über Arbeitstabellen, Steuerdatensätze, Sequenzdateien, Umgebungsvariablen oder Benennungskonventionen statt über ausdrückliche Aufrufe. Ein Batchjob schreibt ein Statusbyte, ein späterer Job deutet es als Erlaubnis, ein Konto zu überspringen. Ein Schemadiagramm zeigt dieses Verhalten nicht. Die Abhängigkeitsanalyse muss Lese- und Schreibzugriffe, Jobreihenfolge und die Lebensdauer von Zwischenzuständen einschließen.
Volumen spielt weiterhin eine Rolle, doch fragen Sie nach Verteilungen und Betriebsgrenzen. Spitzenwert der täglichen Änderung, größte Partition, Datensatzbreite, Aufbewahrung, verspätete Datensätze und erlaubte Ausfallzeit sind wichtiger als eine lebenslange Gesamtzahl von Zeilen. Eine Migration innerhalb eines Wartungsfensters hat einen anderen Plan als eine Migration, die Change Capture und wiederholte Abstimmung bei parallelem Betrieb beider Systeme benötigt.
Akzeptieren Sie "Datenbankmigration enthalten" nicht als Messung. Fragen Sie, welche Tabellen Quell-Ziel-Zuordnungen haben, welche Feldbedeutungen ungeklärt sind, welche gespeicherten Routinen in Services wandern, wie viele Abstimmungsregeln existieren und wie ein Rollback nach Schreibvorgängen im neuen System funktioniert. Wer diese Fragen nicht beantworten kann, hat eine Annahme bepreist.
Betriebscode gehört in die Systemgrenze
Scheduler, Deployment-Skripte, Operator-Handbücher, Zugriffsregeln, Monitoring und Wiederherstellungsverfahren gehören zum Anwendungsverhalten. Wer sie aus der Schätzung lässt, erhält einen Ersatz, der eine Demonstration besteht, aber keinen Geschäftstag abschließen kann.
Batch-Landschaften machen das offensichtlich. JCL oder CL können Abhängigkeiten, bedingte Ausführung, Dataset-Zuweisung, Neustartpunkte und Benachrichtigungen definieren. Der Anwendungscode kann einfach aussehen, während das Jobnetz den tatsächlichen Kontrollfluss trägt. Bei Desktop-Systemen spielen Installationsskripte, Registry-Einstellungen, gemeinsame Ordner und geplante Tasks dieselbe Rolle. Bei Webmonolithen schließen Cron-Einträge und manuelle Admin-Aktionen oft die Lücke.
Fragen Sie nach der Zahl geplanter Jobs, Trigger, Deployment-Einheiten, umgebungsspezifischer Einstellungen, Rollen, Alarme, Berichte und dokumentierter Eingriffe durch Operatoren. Verbinden Sie diese dann mit Geschäftsfähigkeiten. Eine Liste ohne Abhängigkeitsgraphen zeigt weder, ob ein fehlgeschlagener Job sicher neu starten kann, noch ob ein Zugang fünfzehn Prozesse blockiert.
Das Wiederherstellungsverhalten braucht direkte Tests. Beenden Sie einen Batch, nachdem er die Hälfte seiner Ausgabe geschrieben hat. Liefern Sie dieselbe Nachricht zweimal. Lassen Sie eine Abhängigkeit nach Annahme eines Requests in einen Timeout laufen. Stellen Sie einen Datenbank-Snapshot wieder her, während noch Arbeit in der Queue liegt. Das alte System kann über Jahre entstandene praktische Antworten auf diese Fälle enthalten, selbst wenn sie niemand dokumentiert hat. Das Rewrite muss sie erhalten oder durch vom Unternehmen genehmigte Entscheidungen ersetzen.
Dieser Bereich zeigt auch, warum eine beliebte Empfehlung falsch ist: "Betrieb nach funktionaler Parität modernisieren." Teams mögen sie, weil sie scheinbar den Umfang senkt. Tatsächlich verschiebt sie die Entdeckung von Anforderungen an Neustart, Reihenfolge, Zugriff und Monitoring, bis das neue Design fest geworden ist. Optische Dashboards können warten. Das Verhalten, das Geld, Datensätze und Jobs nach einem Fehler konsistent hält, kann es nicht.
Betriebsbereitschaft muss als gemessene Arbeit mit Verantwortlichen und Abnahmenachweisen erscheinen. Behandelt ein Angebot sie als kurze Zeile nahe dem Deployment, ist der Preis unvollständig.
Architekturänderungen brauchen zwei getrennte Schätzungen
Die Modernisierung der Architektur und der Erhalt des Verhaltens hängen zusammen, sind aber nicht dieselbe Arbeit. Bepreisen Sie sie getrennt, damit eine Designentscheidung das versprochene Nachweisniveau nicht heimlich senkt. Eine Servicegrenze kann Zuständigkeit und Deployment verbessern, erzeugt aber Verträge, Fehlerfälle und Entscheidungen zur Datenkonsistenz, die der Monolith mit lokalen Aufrufen und einer Transaktion behandelt hat.
Schätzungen für eine Transliteration sehen oft günstig aus, weil sie eine alte Einheit auf eine neue abbilden. Dieser Ansatz kann zufällige Strukturen, globalen Zustand und überholte Deployment-Beschränkungen bewahren. Ein ernstes Rewrite muss Fähigkeiten bestimmen und Grenzen wählen, die zur Zielumgebung passen. Die Schätzung muss die Analyse zum Trennen dieser Fähigkeiten einschließen, nicht nur die Erzeugung entsprechender Syntax.
Der gegenteilige Fehler ist architektonischer Ehrgeiz ohne Budget für Verhalten. Ein Angebot verspricht vielleicht Services, Ereignisse, einen neuen Client und eine neue Datenbank, plant aber wenig Zeit ein, um das tatsächliche Verhalten des bestehenden Systems zu finden. Dieses Team trifft saubere Designentscheidungen anhand eines unvollständigen Modells. Das Ergebnis kann im Diagramm gut aussehen und bei einer Erstattung, einem erneuten Lauf oder einem Teilausfall falsch sein.
Verlangen Sie zwei verbundene Karten. Die Verhaltenskarte verbindet alte Einstiegspunkte, Entscheidungen, Zustandsänderungen und Ausgaben. Die Zielkarte ordnet dieses Verhalten neuen Komponenten zu und nennt die alte Kopplung, die verschwinden soll. Jede verschobene Verantwortung braucht Nachweise auf beiden Seiten: was das alte Verhalten beweist und was den neuen Vertrag beweist. So erkennen Leiter eine absichtliche Modernisierung statt einer Dateikonvertierung mit neuen Verzeichnisnamen.
Übergreifendes Verhalten braucht bei der Zerlegung besondere Aufmerksamkeit. Authentifizierung, Autorisierung, Transaktionsumfang, Idempotenz, Rundung, Gebietsschema, Auditdatensätze und Fehlerabbildung können in vielen alten Modulen vorkommen, weil keine zentrale Grenze existierte. Jede Kopie als eigene Funktion zu zählen bläht die Schätzung auf. Das Anliegen einmal zu zählen und seine vielen beobachtbaren Varianten zu ignorieren, unterschätzt es. Messen Sie die eigenständigen Verhaltensweisen und entwerfen Sie dann die gemeinsame Implementierung.
Leistungsanforderungen gehören in denselben Vergleich. Kopieren Sie nicht jedes zufällige Zeitverhalten des Altsystems, doch bestimmen Sie Fristen mit geschäftlicher Bedeutung: eine Terminalantwort, bevor ein Operator es erneut versucht, ein abgeschlossener Batch vor Öffnung des nächsten Marktes oder ein Export vor der Frist eines Partners. Erfassen Sie aktuelle Verteilungen, wenn Nachweise existieren, und definieren Sie Zielgrenzen. Das vage Versprechen, das neue System werde schneller, trägt keine Abnahme.
Die Architektur verändert auch den Umstiegsplan. Ein einziges Ersatzereignis verlangt vollständige Parität und einen glaubwürdigen Rollback, bevor Verkehr umgeleitet wird. Ein schrittweiser Ersatz braucht Routingregeln, Datenflüsse für die Koexistenz und Nachweise, dass alte und neue Komponenten während des Übergangs übereinstimmen. Keiner der Ansätze ist immer günstiger. Die Schätzung sollte die jeweils nötige temporäre Technik und den Zeitpunkt ihrer Entfernung zeigen.
Wenn Prüfer Verhaltenserhalt und Zieldesign als getrennte Zeilen sehen, werden Abwägungen ehrlich. Sie können eine Zielgrenze vereinfachen, ohne zu behaupten, eine alte Regel sei verschwunden, oder eine alte Regel durch eine ausdrückliche Geschäftsentscheidung entfernen. Diese Kontrolle braucht eine technische Leitung, bevor sie eine feste Zahl akzeptiert.
Ein gewichtetes Modell macht Annahmen sichtbar
Eine brauchbare Schätzung für ein Software-Rewrite verbindet gemessene Dimensionen und zeigt, wie jede den Aufwand beeinflusst. Sie braucht keine universelle Formel. Sie braucht ein Modell, das Prüfer hinterfragen, aktualisieren und mit Nachweisen verbinden können.
Beginnen Sie mit einer Inventartabelle auf Subsystemebene. Eine Zeile pro Deployment-Einheit oder zusammenhängender Geschäftsfähigkeit ist meist aussagekräftiger als eine Zeile pro Repository. Verwenden Sie beispielsweise diese Spalten:
| Dimension | Was zu erfassen ist | Warum es die Arbeit verändert |
|---|---|---|
| Quellcodevolumen | Handgeschriebener Produktionscode nach Sprache | Bestimmt Prüfungs- und Ersatzvolumen |
| Kontrollfluss | Komplexe Routinen, Verschachtelung, ungelöste Aufrufe | Bestimmt Pfadsuche und Fixture-Arbeit |
| Grenzen | Verträge, Eigentümer, Testersatz | Bestimmt Koordination und Fehlertests |
| Daten | Zuordnungen, verborgene Codes, Migrationsmodus | Bestimmt Transformation und Abstimmung |
| Testoberfläche | Abspielbare Eingaben und vergleichbare Ausgaben | Bestimmt Nachweiserstellung und Abnahme |
| Betrieb | Jobs, Neustartpunkte, Rollen, Alarme | Bestimmt Produktionsreife |
Bewerten Sie das Vertrauen neben jeder Messung. "42 Schnittstellen, 39 geprüft, 3 abgeleitet" ist nützlicher als "42 Schnittstellen." Erfassen Sie die Nachweisquelle, etwa statische Analyse, Produktionstrace, Konfigurationsscan, Interview oder Beispieldaten. Ein abgeleiteter Punkt braucht mehr Reserve als ein beobachteter.
Drücken Sie die Schätzung anschließend als Spannen nach Arbeitsstrom aus. Ein einfaches internes Modell könnte so aussehen:
replacement = source inventory adjusted for repetition and generated code
behavior proof = consequential paths x fixture cost x evidence gap
integration work = contract implementation + failure proof + owner delay risk
data work = mapping + transformation + rehearsal + reconciliation
operations = deployment + observability + recovery exercises
Machen Sie aus dieser Skizze keine Scheingenauigkeit. Die Multiplikatoren müssen aus abgeschlossenen Projekten des Lieferteams stammen, und die Einheiten brauchen Definitionen. Der Zweck besteht darin offenzulegen, warum zwei ähnlich große Systeme unterschiedliche Schätzungen erhalten.
Spannen sollten mit besseren Nachweisen enger werden. Vor dem Codezugriff kann ein Angebot breite Grenzen und ausdrückliche Annahmen enthalten. Nach Repository-Analyse, Stichproben des Verkehrs und Integrationsinterviews sollte der Anbieter Annahmen durch Zahlen ersetzen. Bleibt die Zahl fest, obwohl sich die Nachweise ändern, war die ursprüngliche Schätzung wahrscheinlich ein kommerzielles Ziel statt eines technischen Ergebnisses.
CodeHero liest die gesamte Codebasis über mehrere Sprachen und nutzt aufgezeichneten Produktionsverkehr in einem Paritätsharness. Dadurch kann seine Schätzung Quellstruktur mit beobachtbarem Verhalten verbinden, statt für jede Zeile denselben Satz anzusetzen. Das entschuldigt weiterhin keine unklaren Eingaben: Technische Leiter sollten fragen, was gezählt wurde, wofür der Verkehr steht und welche Grenzen unbewiesen bleiben.
So scheitert eine Schätzung bei einem kleinen System
Betrachten wir eine Anwendung zur Preisberechnung von Versicherungsfällen mit 38.000 Zeilen. Ein Angebot auf Zeilenbasis lässt sie überschaubar wirken. Das Repository enthält einen Desktop-Client, eine Berechnungsbibliothek, SQL-Prozeduren und einen nächtlichen Export. Vorhandene Tests decken die Berechnungsbibliothek ab, und das Team behandelt den Rest zunächst als gewöhnliche Infrastruktur.
Die Discovery findet vier Tatsachen. Der Client wählt Berechnungspfade, indem er Felder aktiviert und deaktiviert, bevor er die Bibliothek aufruft. Produktregeln liegen in sechs SQL-Tabellen, die der Betrieb pflegt. Der nächtliche Export wird nur akzeptiert, wenn seine Trailer-Summen mit einer unabhängigen Berechnung des Partners übereinstimmen. Die Neuberechnung eines historischen Falls hängt von der Version der Regeltabelle ab, die am ursprünglichen Leistungsdatum galt.
Keine dieser Tatsachen fügt viele Quellcodezeilen hinzu. Jede vergrößert das zu erfassende Verhalten. Clientzustand wird zu einem Eingabevertrag. Regeltabellen brauchen versionierte Fixtures und Migrationsregeln. Die Trailerlogik braucht Partnerbeispiele und Ablehnungstests. Historische Neuberechnung braucht zeitbezogene Datenrekonstruktion.
Nehmen wir nun an, die aktuelle Testsuite führt 85 Prozent der Berechnungsbibliothek aus. Die Zahl klingt beruhigend, deckt aber nur die Komponente ab, deren Eingaben der Client bereits verändert hat. Ein Paritätsplan muss Benutzeraktion, Clientzustand, ausgewählte Regelversion, Datenbankänderungen, Berechnungsausgabe und Exportdatensatz erfassen. Die nützliche Testoberfläche reicht von Ende zu Ende, auch wenn die Zielarchitektur diese Anliegen sauber trennt.
Die Schätzung ändert sich, weil sich die Arbeitseinheit von ersetzten Zeilen zu bewiesenen Verhaltensweisen gewandelt hat. Das Team schreibt vielleicht weiterhin nur 38.000 Zeilen neu. Es muss zusätzlich UI-Entscheidungspfade finden, Regelhistorie extrahieren, die Partnervalidierung emulieren und alte sowie neue Ausgaben für aufgezeichnete Fälle vergleichen. Das als Überschreitung zu bezeichnen wäre unehrlich, wenn das ursprüngliche Angebot diese Punkte nie gemessen hat.
Wenn die Discovery diese Form zeigt, gibt es eine praktische Reaktion. Frieren Sie den Festpreis ein, bis der Anbieter das Grenzinventar und den Paritätsplan liefert. Vor der Vertragsunterschrift müssen nicht alle Tests geschrieben sein, aber Sie brauchen Zahlen, Nachweisquellen, Ausschlüsse und eine Methode, um Unbekanntes in Entscheidungen umzuwandeln. Sonst überträgt der Vertrag ein nicht bestimmbares Risiko auf dem Papier, während beide Seiten später darüber streiten.
Vor der Unterschrift das Messpaket verlangen
Eine technische Leitung sollte die Schätzung und die Nachweise dahinter erhalten. Eine glänzende Gesamtsumme ohne Messpaket verhindert die technische Prüfung und macht spätere Diskussionen über den Umfang fast unvermeidlich.
Das Paket sollte eine kompakte Reihe von Fragen beantworten:
- Welche Quellcodekategorien wurden gezählt, was wurde ausgeschlossen und können wir das Inventar erneut erzeugen?
- Wo liegen die tiefsten und folgenreichsten Entscheidungspfade, einschließlich ungelöster dynamischer Aufrufe?
- Welche externen Verträge existieren, wer besitzt sie und welche lassen sich außerhalb der Produktion testen?
- Welche Datenbedeutungen, Migrationen und Abstimmungsregeln sind noch ungeklärt?
- Welche Eingaben lassen sich abspielen, welche Ausgaben vergleichen und wie werden akzeptable Unterschiede normalisiert?
Verlangen Sie die Antworten nach Subsystem, mit Vertrauenskennzeichen und Nachweisquellen. Ein Durchschnitt über das ganze Repository reicht nicht. Eine untestbare Abrechnungsschnittstelle kann das Risiko dominieren, während fünfzig gewöhnliche Module den Durchschnitt harmlos aussehen lassen.
Die kaufmännischen Bedingungen sollten den Messungen folgen. Ein fester Umfang funktioniert, wenn Grenzen und Abnahmenachweise bekannt sind. Eine bezahlte Discovery-Phase kann sinnvoll sein, wenn Zugriffe, Eigentümer oder Produktionstraces fehlen. Sie sollte aber wiederverwendbare Artefakte statt eines Foliensatzes liefern: Inventare, Graphen, Zuordnungen, Beispiele und eine aktualisierte Spanne. Reserve muss an benannte Unbekannte gebunden sein und schrumpfen, wenn der Kunde sie klärt.
Lehnen Sie Schätzungen ab, die Präzision ohne Ausschlüsse anbieten. Lehnen Sie auch das Gegenteil ab, wenn ein Anbieter alles für ungewiss erklärt und unbegrenzt Zeit verlangt. Gute Schätzung verringert Unsicherheit durch Codeprüfung, Verfolgung des Verhaltens und Tests an Grenzen. Sie zeigt, welche Unbekannten bleiben und wer sie entfernen kann.
CodeHero verpflichtet sich zur Lieferung in weniger als 30 Tagen. Deshalb ist die frühe Messung von Code, Verhalten, Integrationen, Daten und Betrieb zwingend. Für welchen Anbieter Sie sich auch entscheiden, bestehen Sie darauf, dass die Schätzung das testbare System benennt, das er liefern will. Eine Zeilensumme beschreibt das Material auf dem Boden. Das Messpaket beschreibt das Gebäude, das er fertigstellen muss.
FAQ
Wie genau ist eine Rewrite-Schätzung anhand von Codezeilen?
Sie ist nur als Maß für den Prüfungsumfang des Quellcodes genau. Der Preis kann um ein Vielfaches falsch liegen, wenn eine kleine Codebasis tiefe Verzweigungen, verborgene Datenregeln, schwache Tests oder außerhalb der Produktion nicht testbare Grenzen hat.
Was sollte von einer Zählung der Codezeilen ausgeschlossen werden?
Weisen Sie generierten Code, eingebundene Abhängigkeiten, Kommentare, Tests, Konfiguration und Produktionscode getrennt aus, statt sie aus einer Gesamtsumme zu löschen. Ausschlüsse müssen dokumentiert und reproduzierbar sein, weil generierter Code und Betriebskonfiguration dennoch Teile des Rewrites beeinflussen.
Sagt zyklomatische Komplexität die Kosten eines Rewrites voraus?
Kein einzelner Komplexitätswert sagt die Kosten voraus. Nutzen Sie zyklomatische Komplexität, um unabhängige Pfade zu finden, und prüfen Sie dann Verschachtelung, veränderlichen Zustand, dynamische Aufrufe und geschäftliche Folgen, um Discovery und Paritätsnachweise zu planen.
Wie beeinflussen externe Integrationen ein Rewrite-Angebot?
Jede Grenze bringt Vertragsarbeit, Fehlerbehandlung, Koordination, Zugangsdaten und Nachweise mit. Ein schlecht dokumentierter Dateiaustausch ohne Testendpunkt kann teurer zu prüfen sein als mehrere gewöhnliche APIs, deshalb sollte das Angebot Implementierung und Test getrennt zeigen.
Was ist die Testoberfläche eines Altsystems?
Die Testoberfläche umfasst die Eingaben, die Sie anstoßen können, und die Ausgaben oder Nebeneffekte, die Sie vergleichen können. Dazu gehören Requests, Dateien, Datenbankänderungen, Nachrichten, Berichte, Fehler und Betriebsergebnisse, nicht nur die mit dem Quellcode gespeicherten Unit-Tests.
Kann Produktionsverkehr zum Testen eines Rewrites dienen?
Ja, aufgezeichneter Verkehr kann realistische Paritätsfälle liefern, wenn das Team sensible Daten schwärzt, benötigten Zustand rekonstruiert und gefährliche Nebeneffekte blockiert. Er ersetzt keine gezielten Tests für seltene Zweige, Fehler, Zeitgrenzen oder Fälle außerhalb des Aufzeichnungsfensters.
Warum machen Datenmigrationen kleine Rewrites teuer?
Der Aufwand folgt Datenbedeutung und Kopplung statt der Datenbankgröße. Überladene Felder, historische Regelversionen, Stored Procedures, ungültige Datensätze und strenge Abstimmung können viel Analyse und Nachweis verlangen, obwohl die Zeilenzahl gering ist.
Sollten Betriebsskripte zum Rewrite-Umfang gehören?
Ja. Scheduler, Deployment-Skripte, Zugriffsregeln, Alarme, Neustartpunkte und Operator-Verfahren bestimmen, ob der Ersatz laufen und sich erholen kann. Wer sie bis nach der funktionalen Parität verschiebt, vertagt Anforderungen, die die Architektur verändern können.
Welche Nachweise sollten einen festen Rewrite-Preis begleiten?
Verlangen Sie wiederholbare Quellcodezählungen, Komplexitätsverteilungen, Grenz- und Dateninventare, einen Plan zum Verhaltensvergleich, Betriebsumfang, Ausschlüsse, Vertrauenskennzeichen und benannte Unbekannte. Der Preis sollte sich pro Subsystem auf diese Artefakte zurückführen lassen.
Wann ist eine bezahlte Discovery vor einem Rewrite sinnvoll?
Bezahlte Discovery ist sinnvoll, wenn dem Anbieter Codezugriff, Produktionstraces, Integrationseigentümer oder repräsentative Daten fehlen. Sie sollte mit wiederverwendbaren technischen Artefakten und einer engeren Schätzung enden, nicht mit einer Präsentation, die die ursprünglichen Unbekannten bestehen lässt.