Welche Ansätze kann ich verfolgen, um die Wahrscheinlichkeit zu verringern, dass in einer komplexen Legacy-App neue Fehler auftreten?

10

Wo ich arbeite, muss ich oft in einem alten System (.NET 1) entwickeln (und Fehler beheben), dessen Code vollständige Spaghetti sind - ohne Rücksicht auf Variablennamen, Programmstruktur oder Kommentare.

Aus diesem Grund brauche ich Ewigkeiten, um zu verstehen, welche Bits geändert werden müssen, und ich "kaputt" oft die vorhandene Software, weil ich eine Änderung vorgenommen habe. Ich möchte wirklich wirklich ein paar Monate (mit Kollegen) damit verbringen, es zu überarbeiten, aber bestehende Entwickler können die Notwendigkeit nicht erkennen - und denken auch nicht, dass dafür Zeit ist (das System ist riesig).

Ich fürchte, ich muss an seinem Code arbeiten, da es Tage dauert, um etwas zu reparieren, nur um herauszufinden, dass ich etwas anderes kaputt gemacht habe. Das lässt mich offensichtlich inkompetent aussehen - wie kann ich damit umgehen?

Billy Bob
quelle

Antworten:

16

Schreiben Sie Tests für die Teile, an denen Sie arbeiten. Sie können einen Workflow ausprobieren, der ungefähr so ​​aussieht:

  1. Schreiben Sie Tests für das Teil, das Sie ändern möchten. Dies hilft Ihnen auch zu verstehen, wie sich der vorhandene Code verhält.
    • Refactor-Code zur Unterstützung von Tests, falls erforderlich. Wenn die Zeit knapp ist, möchten Sie möglicherweise Tests ohne Einheit schreiben.
  2. Führen Sie Ihre Tests durch, um sicherzustellen, dass die Dinge wie erwartet funktionieren.
  3. Nehmen Sie Ihre Änderungen vor. Refactor bei Bedarf im Sinne einer kontinuierlichen Codeverbesserung, aber lassen Sie sich nicht mitreißen.
  4. Führen Sie Ihre Tests erneut aus, um sicherzustellen, dass Sie dieselbe Funktionalität beibehalten.

Wenn Sie Ihre Tests nicht wegwerfen, werden Sie im Laufe der Zeit eine Testsuite erstellen, die die wichtigsten (und / oder flüchtigen) Teile der Anwendung abdecken sollte, und Änderungen daran werden einfacher und sicherer.

Möglicherweise ist es auch hilfreich, effektiv mit Legacy-Code von Michael Feathers zu arbeiten.

Adam Lear
quelle
1
+1 für "... aber Sie möchten möglicherweise Tests ohne Einheit schreiben, wenn die Zeit knapp ist."!
Marcie
1
Gute Antwort. @ m.edmondson Möglicherweise stellen Sie beim Refactor auch fest, dass bestimmte Teile des Codes "riesig" sind, da es überall Duplikate gibt und dass sie beim Refactor sowohl kleiner als auch einfacher werden.
Alb
6

Ich mag folgen Uncle Bob Martin ‚s Boy Scout - Regel :

"Wenn Sie ein großes, unordentliches Vermächtnis haben, müssen Sie nur ... aufhören, die Unordnung zu machen und sie aufzuräumen.

Dies bedeutet nicht, dass Sie Ihre Manager in einen Konferenzraum rufen und ihnen mitteilen, dass Sie in den nächsten drei Monaten keine Funktionen bereitstellen werden, während Sie den Code überarbeiten. Mach das nicht! Es bedeutet vielmehr, dass Sie die „Pfadfinder-Regel“ übernehmen und jedes Modul etwas sauberer prüfen als beim Auschecken.

Von Iteration zu Iteration und von Release zu Release werden Sie dieses System bereinigen und ihm weiterhin neue Features und Funktionen hinzufügen. Es geht nicht anders."

Jesse C. Slicer
quelle
2

Sie können dem Manager erklären, dass Korrekturen, die Stunden dauern sollten, aufgrund der Unordnung in der Codebasis Tage dauern. Die anderen Entwickler sehen keine Notwendigkeit für ein Refactoring, wenn sie die ursprünglichen Entwickler sind - sie kennen das System in- und auswendig, aber das Management sollte wissen, dass dort ein Risiko besteht, wenn diese Entwickler jemals gehen und ihr Wissen mitnehmen.

Ein vollständiges Refactoring ist normalerweise nicht möglich. Daher wird häufig ein kleines Refactoring gleichzeitig durchgeführt - ein paar Methoden oder ein Modul. Wenn es mehrere Tage dauert, um eine Lösung zu finden, können Sie möglicherweise gleichzeitig ein kleines Refactoring des problematischen Moduls einfügen.

FrustratedWithFormsDesigner
quelle
1
Ich bin damit einverstanden - und in der Vergangenheit habe ich diese "kleinen" Refaktoren aufgenommen, wie ich es einfach brauchte, um den Code zu verstehen -, aber normalerweise kommt jemand mit "Sie haben ihn komplett kaputt gemacht" und setzt ihn wieder auf den Stand zurück ...
billy.bob
@ m.edmondson: Ah. Nun, wenn sie eine umfassende Reihe von Komponententests hätten, würde eine einfache Ausführung überprüfen, ob der Refactor gut war oder nicht. Wie es sich anhört, haben sie das nicht, also müssen Sie die Komponententests selbst schreiben. Ich weiß, dass es nicht einfach ist und es keine endgültige Antwort auf dieses Problem gibt (zumindest keine, die ich gefunden habe, obwohl ich beobachten werde, was andere Leute vorschlagen, da ich auch dort war).
FrustratedWithFormsDesigner
2

Müssen Sie wirklich Monate damit verbringen, den Code zu überarbeiten? Oder können Sie den Code überarbeiten, während Sie Änderungen vornehmen? Wenn Sie beispielsweise feststellen, dass die Foo-Methode geändert werden muss, können Sie die Gelegenheit nutzen, die Foo-Methode umzugestalten. Und wenn Sie ein Dutzend anderer Methoden durchlaufen müssen, um herauszufinden, dass Foo das Problem ist, können Sie Kommentare in diesen Methoden hinterlassen, damit Sie oder jemand anderes in Zukunft weiß, was der Code tun soll. Das bedeutet natürlich, dass es immer noch einen Stapel Spaghetti-Code gibt, aber Sie können zumindest die Codebasis in die richtige Richtung bewegen und es sich später leichter machen. Es wird ein großer Verkauf sein, mehrere Monate Zeit zu haben, um Code umzugestalten, da dies bedeutet, dass Sie während der gesamten Zeit nichts liefern, was der Endbenutzer möchte.

Wenn Sie Unit-Tests erstellen (oder hoffentlich die vorhandene Testsuite erweitern), ist es weniger wahrscheinlich, dass Sie versehentlich etwas kaputt machen.

Justin Cave
quelle
0

Ein weiterer Tipp. Wenn sich die Insekten manifestieren und nach dem Anlegen des Verbandes nicht aufhören!

Fragen Sie die fünf Gründe, nehmen Sie die rote Pille und sehen Sie, wie tief das Kaninchenloch ist, und beheben Sie die Grundursache (und den Weg dort unten).

Sie lernen viel über das System. Es hilft bei der Priorisierung, was repariert und umgestaltet werden soll. Und nach ein paar solchen Fahrten haben Sie einige solide "Stützbalken", um den monolithischen Haufen Spaghetti zu stärken.

Maglob
quelle
0

Sie können auch alten Code beibehalten, bis Sie absolut sicher sind, dass Ihre Änderungen schalldicht sind. Nur wenn alle Ihre Änderungen vorliegen, können Sie sie zur Laufzeit umschalten und schnell den Ort eines neuen Regressionsfehlers bestimmen:

// old code
...

if (!File.ReadAllText("c:\patch_control.txt").Contains("StrangeUIBugFix=0"))
{
    // new code goes here
    ...
}

// old + new code
int someValue = 
    IsEnabled("StrangeUIBugFix") ? a + b :  // new code
    a * b; // old code
AareP
quelle
0

Eine Sache: Never change any existing code if you are not sure what effect change would have on complete application.

Rachel
quelle