Ich habe vor kurzem einen neuen Job angefangen, bei dem ich an einer sehr großen Anwendung arbeite (15M loc). In meinem vorherigen Job hatten wir eine ähnlich große Anwendung, aber (im positiven oder im negativen Sinne) verwendeten wir OSGi, was bedeutete, dass die Anwendung in viele Mikrodienste unterteilt war, die unabhängig voneinander geändert, kompiliert und bereitgestellt werden konnten. Die neue Anwendung ist nur eine große Codebasis mit möglicherweise ein paar DLLs.
Also muss ich das Interface dieser Klasse ändern, weil mein Chef mich darum gebeten hat. Sie haben es anfangs mit einigen Annahmen geschrieben, die sich nicht allzu gut verallgemeinern ließen, und eine Weile haben sie das Problem des Refactoring vermieden, weil es so eng miteinander verbunden ist. Ich habe die Benutzeroberfläche geändert und jetzt gibt es über 25000 Fehler. Einige der Fehler sind in Klassen mit wichtigen klingenden Namen wie "XYZPriceCalculator" die reaaallysollte nicht brechen. Ich kann die Anwendung jedoch nicht starten, um zu überprüfen, ob sie funktioniert, bis alle Fehler behoben sind. Viele der Unit-Tests verweisen entweder direkt auf diese Schnittstelle oder sind an Basisklassen gekoppelt, die auf diese Schnittstelle verweisen. Daher ist es eine ziemlich große Aufgabe, diese zu beheben. Außerdem weiß ich nicht wirklich, wie all diese Teile zusammenpassen, und selbst wenn ich anfangen könnte, weiß ich nicht wirklich, wie es aussehen würde, wenn die Dinge kaputt wären.
Bei meinem letzten Job war ich noch nie mit einem solchen Problem konfrontiert. Was mache ich?
quelle
Antworten:
25000 Fehler bedeuten im Grunde genommen "Fass das nicht an". Ändere es zurück. Erstellen Sie eine neue Klasse mit der gewünschten Schnittstelle und verschieben Sie die Konsumenten der Klasse langsam auf die neue. Abhängig von der Sprache können Sie die alte Klasse als veraltet markieren, was möglicherweise alle möglichen Compiler-Warnungen auslöst, Ihren Build jedoch nicht beschädigt.
Leider passieren diese Dinge in älteren Codebasen. Es gibt nicht viel, was Sie dagegen tun können, außer die Dinge langsam zu verbessern. Stellen Sie beim Erstellen der neuen Klassen sicher, dass Sie sie ordnungsgemäß testen und mit SOLID-Prinzipien erstellen, damit sie in Zukunft leichter geändert werden können.
quelle
Teile und erobere mit Refactorings
Oft hilft es, die Änderungen, die Sie vornehmen müssen, in kleinere Schritte aufzuteilen, da Sie dann die meisten kleineren Schritte so ausführen können, dass die Software überhaupt nicht beschädigt wird. Refactoring-Tools helfen bei solchen Aufgaben sehr.
Teilen
Identifizieren Sie zunächst die kleinstmöglichen Änderungen (in Bezug auf logische Änderungen, nicht in Bezug auf geänderte LoC), die sich zu der Änderung summieren, die Sie erreichen möchten. Versuchen Sie insbesondere, Schritte zu isolieren, die reine Refactorings sind und von Werkzeugen ausgeführt werden können.
Erobern
In komplizierten Fällen wie Ihrem kann es sinnvoll sein, jeweils ein kleines Refactoring durchzuführen und das Problem dann zu beheben, damit alle Systeme für die kontinuierliche Integration die Änderung überprüfen können. Vielleicht hat sich auch das Testteam darum gekümmert. Dadurch werden die von Ihnen ausgeführten Schritte überprüft.
Um ein bestimmtes Refactoring durchführen zu können, benötigen Sie unbedingt Tool-Unterstützung für einen Fall, in dem Sie 25.000 Aufrufseiten der zu ändernden Methode haben. Vielleicht funktioniert das Suchen und Ersetzen auch, aber für einen so kritischen Fall hätte ich Angst davor.
Beispiel
In C # ist es beispielsweise möglich, mit Resharper die Signatur einer Methode zu ändern . Wenn die Änderung einfach genug ist, z. B. das Hinzufügen eines neuen Parameters, können Sie angeben, welcher Wert an Aufrufstandorten verwendet werden soll, an denen andernfalls ein Kompilierungsfehler auftreten würde.
Sie haben dann sofort eine fehlerfreie Codebasis und können alle Unit-Tests durchführen, die bestehen bleiben, da es sich nur um ein Refactoring handelte.
Sobald die Signatur der Methode gut aussieht, können Sie die Werte ersetzen, die Resharper als Argumente für den neu eingeführten Parameter hinzugefügt hat. Dies ist kein Refactoring mehr, aber Sie haben eine fehlerfreie Codebasis und können die Tests nach jeder Zeile, die Sie ändern, ausführen.
Manchmal klappt das nicht
Dies ist ein sehr nützlicher Ansatz für Fälle wie Ihren, in denen Sie viele Anrufseiten haben. Und Sie haben jetzt eine funktionierende Software, so dass es möglich sein kann, kleine Umgestaltungsschritte durchzuführen, um die Signatur nur ein wenig zu ändern, und dann noch einen zu machen.
Leider funktioniert es nicht, wenn die Signaturänderung zu komplex ist und nicht in kleinere Änderungen unterteilt werden kann. Das ist aber selten; das Problem in kleinere Probleme Spaltung in der Regel zeigt , dass es ist möglich.
quelle
Klären Sie Ihre Aufgabe mit Ihrem Chef, damit dieser das Problem und Ihre Bedürfnisse als professioneller Softwareentwickler versteht.
Wenn Sie Teil eines Teams sind, suchen Sie den Hauptentwickler und fragen Sie ihn um Rat.
Viel Glück.
quelle
Fass es nicht an. Mach nichts.
Setzen Sie sich stattdessen auf Ihren Stuhl und rufen Sie "Heeeeelp !!!!!" so laut du kannst.
Nun, nicht genau so, aber fragen Sie einen Ihrer älteren Kollegen um Rat. Wenn Sie 25.000 Fehler haben, beheben Sie die Fehler nicht, sondern die Fehlerursachen. Und ein leitender Kollege sollte Sie beraten können, wie Sie die von Ihrem Chef gewünschten Änderungen vornehmen können, ohne dass 25.000 Fehler auftreten. Es gibt verschiedene Möglichkeiten, dies zu tun, aber was ein guter Weg ist, hängt von Ihrer spezifischen Situation ab.
Und es könnte sein, dass der Chef Ihren älteren Kollegen befohlen hat, die gleiche Änderung vorzunehmen, und sie sagten "Nein". Weil sie wussten, was passieren würde. Deshalb haben Sie den Job bekommen.
quelle
Verankerte APIs können nicht einfach geändert werden. Wenn Sie sie wirklich ändern müssen, müssen Sie sie als veraltet dokumentieren (mit welchen Mitteln auch immer die Sprache dies zulässt) und dokumentieren, welche API stattdessen verwendet werden soll. Die alte API kann dann langsam auslaufen ... möglicherweise sehr langsam, abhängig von Ihrem Zeitbudget für das Refactoring.
quelle
Bewerten
Prüfen Sie, ob diese Änderung erforderlich ist oder ob Sie eine neue Methode hinzufügen und die andere ablehnen können.
Nach vorne
Wenn ein Wechsel notwendig ist; dann ist ein Migrationsplan notwendig.
Der erste Schritt besteht darin, die neue Methode einzuführen und die Argumente der alten Methode zu massieren, damit sie die neue aufrufen kann. Möglicherweise müssen einige Dinge hartcodiert werden. das ist gut.
Dies ist ein Festschreibungspunkt: Überprüfen Sie, ob alle Tests bestanden, festgeschrieben oder übertragen wurden.
Wandern
Die beschäftigte Arbeit migriert alle Aufrufer der alten Methode auf die neue. Zum Glück kann es dank des Spediteurs schrittweise erfolgen.
Also mach weiter; Zögern Sie nicht, Hilfsmittel zu verwenden (da
sed
es die grundlegendsten sind, gibt es andere).Markieren Sie die alte Methode als veraltet (mit einem Hinweis auf die neue Methode). Es wird Ihnen helfen, festzustellen, ob Sie etwas vergessen haben, und es wird Ihnen helfen, wenn ein Mitarbeiter die alte Methode aufruft, während Sie daran arbeiten.
Dies ist ein Festschreibungspunkt (oder mehrere Festschreibungspunkte): Überprüfen Sie, ob alle Tests bestanden, festgeschrieben oder übertragen wurden.
Entfernen
Nachdem einige Zeit vergangen ist (vielleicht nur ein Tag), entfernen Sie einfach die alte Methode.
quelle
sed
ist wahrscheinlich eine schlechte Idee ... Etwas, das die Sprache "versteht" und keine unbeabsichtigten drastischen Änderungen vornimmt, ist besser..c_str()
zum Beispiel einen Aufruf ) und neue Argumente einzuführen.sed
irgendwie funktioniert, fängt der Compiler seine Probleme danach.sed
(odered
) kann für diese Art von Dingen angemessen sein - vorausgesetzt, Sie überprüfen den Diff vor dem Festschreiben ordnungsgemäß.Wenn Ihre Änderung an der Methodensignatur lediglich eine Namensänderung ist, können Sie die Änderung in den 25.000 Klassen, die auf die betreffende Methode verweisen, mithilfe von Tools automatisieren.
Ich gehe davon aus, dass Sie den Code einfach manuell bearbeitet haben, was zu allen Fehlern geführt hat. Ich gehe auch davon aus, dass Sie mit Java vertraut sind (siehe Ihren Verweis auf OSGi). In Eclipse (ich weiß nicht, welche Programmierumgebung Sie verwenden, aber in anderen Umgebungen gibt es ähnliche Refactoring-Tools) können Sie also "Refactoring -> Umbenennen" verwenden. um alle Verweise auf die Methode zu aktualisieren, die Sie ohne Fehler verlassen sollten.
Falls Sie andere Änderungen an der Methodensignatur vornehmen, als nur umzubenennen (Ändern der Anzahl oder der Arten von Parametern), können Sie "Refactoring -> Methodensignatur ändern" verwenden. Es besteht jedoch die Möglichkeit, dass Sie vorsichtiger sein müssen, wie die anderen Antworten nahelegen. Unabhängig von der Art der Änderung kann es auch noch eine ziemliche Aufgabe sein, all diese Änderungen in einer ausgelasteten Codebasis durchzuführen.
quelle
Hier mein Beitrag.
Sie kennen das Projekt und seine "Features" wahrscheinlich nicht. Bevor Sie eine einzelne Codezeile eingeben, müssen Sie mit dem Projekt vertraut sein. Machen Sie also Ihre Änderungen rückgängig und analysieren Sie zunächst den Code . (Zumindest der Betroffene)
Wenn Sie die vorhandene Lösung verstehen, erhalten Sie eine bessere Übersicht darüber, wo Sie sich befinden. Stellen Sie die Lösung und ihre Bedeutung in einen Kontext.
Wie @Greg hervorhob, sollten Sie in der Lage sein, den vorhandenen Code zu testen, um eine gültige Referenz zum Vergleich zu erhalten (Regressionstests). Ihre Lösung sollte in der Lage sein, dieselben Ergebnisse wie die vorhandene Lösung zu erzielen . Zu diesem Zeitpunkt haben Sie es egal , ob die Ergebnisse stimmen . Das erste Ziel ist die Umgestaltung und nicht die Behebung von Fehlern. Wenn die vorhandene Lösung "2 + 2 = 42" anzeigt, sollte dies auch Ihre Lösung sein. Wenn es keine Ausnahmen gibt, sollten Sie es auch nicht tun. Wenn es Nullen zurückgibt, sollte Ihr auch Nullen zurückgeben. Und so weiter. Andernfalls gefährden Sie 25.000 Codezeilen.
Dies dient der Nachrüstbarkeit.
Warum? Denn gerade jetzt ist es Ihre einzigartige Garantie für einen erfolgreichen Refactor.
Eine Möglichkeit, die Nachrüstbarkeit zu gewährleisten, ist für Sie dringend erforderlich. Hier also Ihre erste Herausforderung. Isolieren Sie die Komponente für den Komponententest.
Denken Sie daran, dass diese 25.000 Codezeilen unter der Annahme der möglichen Ergebnisse des vorhandenen Codes erstellt wurden. Wenn Sie diesen Teil des Vertrags nicht brechen, sind Sie auf halbem Weg zur endgültigen Lösung. Wenn du das tust, gut: Möge die Macht mit dir sein
Wenn Sie den neuen "Vertrag" entworfen und implementiert haben, ersetzen Sie den alten. Verwerfe es oder nimm es raus.
Ich habe vorgeschlagen, Fehler in Ruhe zu lassen, da das Refactoring und das Beheben von Fehlern unterschiedliche Aufgaben sind. Wenn Sie versuchen, sie gemeinsam voranzutreiben, schlagen Sie möglicherweise bei beiden fehl. Sie könnten denken, Sie hätten Fehler gefunden, diese könnten jedoch "Merkmale" sein. Also lass sie in Ruhe (für eine Minute).
25.000 Codezeilen scheinen mir genug Probleme zu sein, um mich auf nur eine Aufgabe zu konzentrieren.
Sobald Ihre erste Aufgabe erledigt ist. Zeigen Sie Ihrem Chef diese Bugs / Features auf.
Schließlich, wie @Stephen gesagt hat:
quelle
Probier es aus.
Alle anderen empfehlen die Umgestaltung, damit die Auswirkungen gering sind. Aber mit so vielen Fehlern haben Sie, selbst wenn es Ihnen gelingt, mit nur 10 Codezeilen umzugestalten (was Sie wahrscheinlich können), 25.000 Code-Flows beeinflusst , auch wenn Sie sie nicht neu schreiben mussten.
Als Nächstes müssen Sie sicherstellen, dass Ihre Regressionstestsuite mit Bravour bestanden wird. Und wenn Sie keine haben, dann machen Sie eine, die es will. Das Hinzufügen einer umfassenden Regressionstestsuite zu Ihrem monolithischen Projekt klingt langweilig, ist jedoch eine gute Möglichkeit, das Vertrauen in Release-Kandidaten zu erhöhen und sie schneller freizugeben, wenn die Suite gut automatisiert ist.
quelle