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.
quelle
Antworten:
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.
quelle
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.
quelle
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.
quelle
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.
quelle