Wie kann ich eine große Legacy-Codebasis aktualisieren, um bestimmte Qualitätsstandards zu erfüllen?

10

Es gibt viele Informationen zu Tools und Techniken zur Verbesserung älterer Codebasen, aber ich habe keine erfolgreichen Fallstudien aus der Praxis gefunden. Die meisten Ratschläge sind auf Mikroebene und obwohl sie hilfreich sind, überzeugen sie viele Menschen nicht, da es an Beweisen mangelt, die auf Makroebene hilfreich sein können.

Ich suche speziell nach inkrementellen Verbesserungen, die sich in der realen Welt als Erfolg erwiesen haben, wenn eine große Legacy-Codebasis aktualisiert wird, um den heutigen Qualitätsstandards zu entsprechen, und nicht nach einer vollständigen Neufassung.

Vor:

  • Groß: größer als 1MLOC
  • Vermächtnis: keine automatisierten Tests
  • Schlechte Qualität: hohe Komplexität, hohe Kopplung, hohe entgangene Defekte

Nach

  • Automatisierte Tests
  • Einfachere Updates / Wartung
  • Hohe Qualität: geringere Komplexität, entkoppelter Code, wenige entgangene Fehler

Welche inkrementellen Schritte wurden in der realen Welt bewiesen, um eine große Legacy-Codebasis erfolgreich zu aktualisieren, um die oben genannten Qualitätsstandards zu erfüllen, ohne sie komplett neu zu schreiben?

Wenn möglich, fügen Sie Ihrer Antwort ein Beispielunternehmen oder eine Fallstudie eines großen Legacy-Projekts bei, das einen "erfolgreichen" Prozess zur Qualitätsverbesserung durchlaufen hat, um es zu sichern.

mikelong
quelle
2
Netscape
Karthik T
7
Die gesamte Finanzbranche? Ein Großteil davon läuft mit 40 Jahre altem FORTRAN-Code. Im Gegensatz zu Netscape können sie es nicht herausschmeißen und von Grund auf neu schreiben, daher hat es sich die ganze Zeit über allmählich verbessert.
MattDavey
2
In meinem POV kann Netscape kaum als erfolgreiches Beispiel dienen - das Projekt beendete das Unternehmen ..... das zu dieser Zeit ein Werbespot für gemeinnützige Organisationen war. Ich kann mir nicht vorstellen, dass die Aktionäre an diesem Tag das oberste Regal sprudelnd aufbrechen. Tatsächlich gibt es ein bekanntes Whitepaper nach dem Motto "Was nicht zu tun ist", in dem Netscape als perfekte Fallstudie verwendet wird.
Mattnz
2
Hallo @mikelong, ich habe Ihre Frage bearbeitet, um zu versuchen, sie wieder zu öffnen. Ihre ursprüngliche Frage nach einer Liste von Beispielen, die nach StackExchange-Standards als "nicht konstruktiv" eingestuft wird. Sie können es gerne weiter bearbeiten , um weitere Details zu dem, was Sie unter "hoher Qualität" verstehen, hinzuzufügen oder den Wortlaut zu aktualisieren, wenn ich einen Fehler gemacht habe. :)
Rachel

Antworten:

8

Bücher wie http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052 sollten bezeugen, wie groß und alt Codebasen von schlechter Qualität in der Branche sind.

Meine Vermutung, warum Sie nicht gehört oder gesehen haben und, was noch wichtiger ist, Sie werden wahrscheinlich nie davon hören, bis Sie selbst an einem von ihnen arbeiten, ist, dass niemand aus verschiedenen Gründen in der Lage zu sein scheint, sauber herauszukommen und zu sagen, dass ihr Code Basis war all das oben Genannte, ohne sich nicht trivialen Auswirkungen zu stellen.

Dies könnte den Mangel an Studien erklären, von denen Sie sprechen. Wenn Sie genug Bücher lesen, zum Beispiel Peter van der Lindens Deep C Secrets, werden Sie über Millionen-Dollar-Bugs lesen, bei denen der Teil, über den das Projekt sie hatte, fehlt.

HINWEIS: Ich wollte dies zu einem Kommentar machen, aber es war zu lang. Ich verstehe, dass dies die Frage nicht vollständig beantwortet.

BEARBEITEN: C ++ 11 & Die langfristige Rentabilität von GCC wird in Frage gestellt. Wenn die Entwickler GCC überarbeiten und es als LLVM / Clang benutzerfreundlicher machen, könnte dies ein gutes Beispiel sein. In der Diskussion wird festgestellt, dass die Dokumentation an einigen Stellen schlecht ist, was die Eintrittsbarriere für neue Entwickler erhöht.

vpit3833
quelle
4

Am 3. Februar 2013 hält Michael Meeks, einer der LibreOffice-Entwickler, in ein paar Tagen einen Vortrag mit dem Titel "LibreOffice: Bereinigen und Umfaktorisieren einer riesigen Codebasis oder warum das Umschreiben noch schlimmer wäre." . " Es klingt genau so, wie Sie es sich wünschen: eine Diskussion darüber, was sie getan haben, um "eine schlecht verstandene, gigantische Codebasis zu nehmen, die ausführlich auf Deutsch kommentiert wurde, ohne Unit-Tests, eine verworrene Build-Infrastruktur und fünfundzwanzig Jahre unbezahlter technischer Schulden "und modernisieren.

Die Präsentation kann online gestreamt werden , und (glaube ich) Aufnahmen werden zu einem späteren Zeitpunkt verfügbar sein.

Josh Kelley
quelle
1
Mir ist klar, dass es in ein paar Tagen geplant ist. Können Sie Ihrer Antwort jedoch nach der Ausstrahlung eine Zusammenfassung des Prozesses hinzufügen, den sie zur Modernisierung ihrer Codebasis unternommen haben, falls diese Links jemals ausfallen sollten?
Rachel
@Rachel - Wenn ich die Sendung sehen kann, werde ich das definitiv tun. Vielen Dank.
Josh Kelley
4

Ich habe in meiner Karriere tatsächlich dreimal ein ziemlich bedeutendes Refactoring durchlaufen. Code neigt zum Verfall. Wenn Ihre Codebasis also lang genug ist, ist ein großer Refactor so gut wie unvermeidlich. Alle meine Beispiele basierten auf privaten Codebasen, was erklären könnte, warum öffentliche Beispiele schwer zu finden sind.

Das erste Mal war eine Anwendung, die, ob Sie es glauben oder nicht, eine grundlegende Architektur hatte, die es ermöglichte, nur mit Nadeldruckern zu arbeiten. Als meine Firma keinen Lieferanten mehr für die Lieferung der Bänder finden konnte, beauftragten sie mich, sie mit einem Laserdrucker arbeiten zu lassen.

Das zweite Mal war eine Migration von mehreren hundert automatisierten Testskripten von C nach Java, teils weil wir bessere plattformübergreifende Fähigkeiten benötigten, teils weil es schwierig wurde, neue C-Entwickler einzustellen.

Das dritte Mal bin ich noch in der Mitte, das eine riesige monolithische Anwendung modularisiert, um Unit-Tests durch Reduzieren der Kopplung und für plattformübergreifende Zwecke zu ermöglichen.

Ich vergleiche die Anstrengung mit dem Bergsteigen. Sie haben dieses große Ziel vor sich, aber Sie gehen es nicht auf Makroebene an. Sie nehmen jeweils einen Haltegriff, haben immer eine enge Fallback-Position und trennen die vorherige Sicherheit erst, wenn die nächste vorhanden ist. Du fängst an, nur kleine inkrementelle Verbesserungen vorzunehmen, und nach einer Weile drehst du dich um und plötzlich gibt es diese schöne Aussicht.

Angenommen, Sie haben beispielsweise 60.000 Dateien mit stark gekoppeltem Code. Sie möchten damit beginnen, es einem Unit-Test zu unterziehen, aber die Abhängigkeiten machen es unmöglich. Wie behebt man das? Sie entkoppeln eine Datei. Sie fügen automatisierte Tests hinzu. Sie kehren zu stabilem Boden zurück, bevor Sie weitermachen. 59.999 mal wiederholen.

Wenn diese einfachen Töne, das ist , weil es ist einfach. Es ist nicht einfach, aber es ist einfach. Es ist zunächst schwer, Fortschritte zu bemerken. Wir sind zwei Jahre in einem scheinbar unmöglichen Refactor und haben wahrscheinlich Jahre vor uns, bis wir fertig sind. Wenn wir jedoch zurückblicken, stellen wir plötzlich fest, wie viel besser der Code bereits geworden ist, und wir konnten weiterhin neue Funktionen bereitstellen an unsere Kunden in der Zwischenzeit.

Die anderen beiden Male arbeiteten auf die gleiche Weise. Sie finden den kleinsten sicheren Schritt, den Sie unternehmen können, und halten ihn, indem Sie die Anwendung immer in einem funktionierenden Zustand halten. Sie sorgen sich nur um das Gesamtbild, um sicherzustellen, dass Sie in die richtige Richtung gehen. Alle Ihre Aktionen sind klein, stetig und inkrementell.

Karl Bielefeldt
quelle
1

Aus persönlicher Erfahrung mit einer millionenschweren Codebasis habe ich einige Strategien gefunden, die zu funktionieren scheinen.

Schauen Sie sich alle Fehler an (auch geschlossene) und versuchen Sie, sie in Kategorien zu unterteilen. Speziell, um zu versuchen, sie nach der Komponente aufzuschlüsseln, zu der sie gehören. Wenn sie zu mehr als einer Komponente gehören, beachten Sie dies. Wenn Sie dies getan haben, schauen Sie sich an, welcher Eimer der größte ist, und bestimmen Sie anhand dessen, wo Sie anfangen sollen. Darüber hinaus können Sie den Versionsverlauf der Dateien anzeigen, um festzustellen, welche Änderungen am meisten vorgenommen wurden, und diesen als Leitfaden für den Start verwenden. Grundsätzlich versuchen Sie, das am meisten kaputte Problem zu finden und zu wiederholen. Außerdem habe ich festgestellt, dass der Versuch, alles gleichzeitig zu reparieren, niemals funktioniert, sondern nur mehr Probleme verursacht.

Wenn Sie feststellen, dass viele Dinge zu mehreren Komponenten gehören, ist dies ein Hinweis auf "System" -Probleme und weist möglicherweise auf Code hin, der zu eng gekoppelt ist, oder auf eine API, die aktualisiert werden muss.

Ein weiterer Bereich, in dem ich viel Zeit verbracht habe, ist das Testen der vorhandenen Codebasis. Hier gibt es mehrere Strategien und alle haben ihre Vorzüge, aber niemand ist eine vollständige Lösung für das Problem.

  • Unit-Tests können funktionieren, aber oft sind Sie aufgrund des eng gekoppelten Codes auf das beschränkt, was Unit-Tests unterzogen werden können. Tun Sie es jedoch, wo Sie können.
  • Externe Tests sind ein weiterer Weg. Ich gehe davon aus, dass Sie dies wahrscheinlich bereits haben und wenn nicht, würde ich einige Zeit damit verbringen, es zu erstellen. Zusätzlich hat es für mich funktioniert, die Möglichkeit hinzuzufügen, Fehler / Ereignisse zufällig in das System einzufügen. Versuchen Sie außerdem, mehrere Dinge gleichzeitig zu injizieren, um zu verhindern, dass sie auf neue Weise fehlschlagen.
barrem23
quelle