Wie gehe ich beim Refactoring einer vorhandenen Webanwendung vor?

10

Ich habe in letzter Zeit viel gelesen und nachgedacht und bin zu dem Schluss gekommen, dass ich vielleicht meine Webentwicklungsstrategie überdenken sollte. Ich programmiere viel im laufenden Betrieb und in den zwei Jahren, in denen ich an einer PHP-Webanwendung gearbeitet habe, wurde das, was als kleines Tool begonnen haben könnte, zu einem ziemlich großen Projekt. Aber es gibt eine Menge Legacy- Code von mir und meinem Vorgänger, ein Codeausschnitt, der zu dieser Zeit vielleicht Sinn gemacht hat, aber jetzt stelle ich die Nützlichkeit dieses Codes in der Form in Frage, wie er tatsächlich ist. Darüber hinaus waren solche Dinge wie Unit-Tests und testgetriebene Entwicklung bis vor kurzem nicht in meinem Anwendungsbereich.

Wie würden Sie das Refactoring der Webanwendung angehen? Nach welchen Dingen sollte ich suchen und in welcher Reihenfolge? Was ist mit Browsergame versus funktionaler Web-App? Würde es dann Unterschiede im Ansatz geben?

Eldros
quelle
4
Wenn es nicht kaputt ist, reparieren Sie es nicht. Verbringen Sie mehr Zeit mit dem Schreiben von Tests und weniger Zeit mit unnötigen Änderungen.
Macneil
Nur aus Interesse. Mit welcher Sprache / Technologie haben Sie Ihre Bewerbung geschrieben? Was ist das für eine Seite? Siehe welie.com/patterns -> Kontext des Designs -> Site-Typen
JW01
@ JW01 Ich verwende PHP für die interne Logik und AJAX für die Ansichtsverwaltung und Formularvalidierung. Dies wäre eine Variante des webbasierten Anwendungsmusters, jedoch nur in einer bestimmten Umgebung verfügbar, da es sich um ein internes Tool handelt.
Eldros
Ich hatte ein völlig anderes Bild Ihrer App im Kopf, als ich die Frage beantwortete. Sie haben so viel mehr Freiheit, die API zu ändern, als wenn sie gemeinfrei wäre.
JW01
@ JW01 Ich wollte nicht zu spezifisch sein, da ich wollte, dass diese Frage auch für andere nützlich ist.
Eldros

Antworten:

6

So oder so nähern Sie sich jeder Art von Legacy-Code. Sie finden ein Stück, das testbar ist, Sie schreiben Tests dafür und Refactor.

Wenn Sie ein Teil nicht leicht testbar finden, müssen Sie es ohne den Sicherheitsgurt einer Testsuite testbar machen. In diesem Fall ändern Sie einen fast testbaren Code sehr sorgfältig, damit er testbar ist.

Code, der keine Dinge für den Browser rendert - "Infrastruktur" -Code, Modelle, datenbankberührende Dinge - ist möglicherweise ein guter Anfang.

Bearbeiten: UI-Test: Mit der Warnung, dass ich hier wenig Erfahrung habe, macht ein Freund von mir dies: Er führt einen Teil des HTML-generierenden Codes aus. Dann hackt er seinen Code und vergleicht den neu generierten Code mit der alten Version (mit diff; er hat nicht den ganzen Weg automatisiert). Änderungen im HTML-Code bedeuten, dass Ihr Refactoring fehlgeschlagen ist.

Frank Shearar
quelle
Wie würden Sie empfehlen, den Teil "Ansicht" einer Legacy-Anwendung zu testen - IE, den Teil HTML / JavaScript / CSS / etc? Ich bin damit einverstanden, dass Unit-Tests der richtige Weg sind, aber das Testen von Anwendungscode scheint schwierig zu automatisieren.
Justin Ethier
Wenn Sie Tests für eine Web-Benutzeroberfläche erstellen, ist der Vergleich von altem HTML mit neuem HTML eine fragile Methode. Ich neige dazu, die Semantik einer Webseite zu identifizieren und diese zu testen. Dh fragen "Hat sich das Web-Impressum (Seitentitel, Überschrift, Schlüsselwörter, ausgehende Links, Formulare) geändert?" nicht "Hat sich der HTML-Code geändert?".
JW01
Sie können Web-Apps mit einem "kopflosen Browser" testen - im Grunde genommen eine Bibliothek, die für einen Komponententest gedacht ist, was ein Browser für einen QS-Mitarbeiter ist. In der Java-Welt gibt es HTMLUnit (reines Java, in sich geschlossen) und WebDriver (steuert einen echten Browser wie FireFox fern). Mein Projekt enthält eine Reihe von Hunderten von Tests, die so geschrieben wurden.
Tom Anderson
@ JW01 Du hast absolut Recht - es ist sehr zerbrechlich. Es ist großartig, um ein Refactoring auf einmalige Weise zu testen: Sie können überprüfen, ob das Refactoring die Ausgabe nicht geändert hat, aber jedes Mal, wenn Sie den generierten HTML-Code ändern, müssen Sie den "neu erwarteten" HTML-Code speichern.
Frank Shearar
10

Es gibt ein großartiges Buch mit dem Titel "Effektiv mit Legacy-Code arbeiten" von Michael Feathers. Seien wir ehrlich, wir haben alle Legacy-Code.

Die Hauptsache ist, den neuen Code, den Sie erstellen, zu testen. Wenn Sie andere Codeteile berühren müssen, finden Sie auch Möglichkeiten, diese zu testen. Es ist ein langer, langsamer Prozess, aber wenn Sie systematisch vorgehen, können Sie das Gesamtprodukt im Laufe der Zeit wirklich verbessern.

Marcie
quelle
3
"Seien wir ehrlich, wir schreiben heute nur die Legacy-Software von morgen." - Martin Fowler
Frank Shearar
3
  • Ja - Webanwendungen unterscheiden sich von Websites

Ich würde sie separat behandeln. Wenn Sie einen Teil Ihrer Website haben, der lediglich eine Sammlung von Dokumenten ist (die für anonyme Benutzer und angemeldete Benutzer gleichermaßen aussehen), unterscheidet sich die beste Strukturierungsmethode stark von einer Web-App, die dynamisch unterschiedliche Seiten bereitstellt an jeden Benutzer. Teilen Sie diese beiden Teile der Website in zwei Apps / Komponenten auf und behandeln Sie jeden Teil anders.

  • Starten Sie die Versionskontrolle

Sobald Ihr Code unter Versionskontrolle steht, können Sie alle unnötigen Codes, die Sie zuvor "nur für den Fall" usw. aufbewahrt haben, durchgehen und sicher entfernen. Ich weiß nicht, wie ich ohne Versionskontrolle überlebt habe.

  • Reduzieren Sie die Unendlichkeiten

Wenn vier verschiedene URLs alle auf dieselbe Ressource verweisen, ist das Problem viel größer. Am Ende haben Sie es mit unendlich vielen URLs zu tun. Stellen Sie so bald wie möglich sicher, dass eine URL-Normalisierungsrichtlinie vorhanden ist. Sobald dies erledigt ist, können Sie semantische Bedeutungen an URLs anhängen und Reverse-Lookups von Ressource zu URL durchführen. Auf diese Weise können Sie das "Web-Impressum" von den "Ressourcen" der Site trennen.

Sie müssen sich fragen: "Wenn Sie eine URL haben, wie lautet ihre normalisierte Form?". Sobald Sie dies festgenagelt haben. Dann können mehr als 50.000 URLs auf Ihrer Website auf 2.000 reduziert werden. Das ist viel einfacher zu verstehen und in Ihrem Kopf zu verwalten.

siehe: http://www.sugarrae.com/be-a-normalizer-a-c14n-exterminator/

  • Beginnen Sie mit der Modellierung von "Was ist" und nicht "Was Sie wollen".

Wenn Sie eine Legacy-Site aufräumen, die von Anfang an nicht unter Berücksichtigung der Best Practice entwickelt wurde, ist es verlockend, von „Chaos“ zu „Idealem Design“ zu springen. Ich glaube, dass Sie dies in mindestens zwei Schritten tun müssen: "Chaos" -> "gut modellierter Legacy-Code" -> "idealer neuer Code mit zusätzlichen Funktionen". Hören Sie auf, Funktionen hinzuzufügen. Konzentrieren Sie sich darauf, das Chaos zu beheben oder es hinter einer Antikorruptionsschicht zu kapseln. Nur dann können Sie beginnen, das Design in etwas Besseres zu verwandeln.

Siehe: http://www.joelonsoftware.com/articles/fog0000000069.html

Siehe: http://www.laputan.org/mud/

  • Es ist eine gute Idee, es zu testen.

Erstellen Sie eine Testsuite / ein Framework und beginnen Sie mit dem Hinzufügen von Tests. Es ist jedoch ziemlich schwierig, alten Code zu testen. Also, lass dich nicht zu sehr darauf ein. Solange Sie das Framework dort haben, können Sie nach und nach Tests hinzufügen.

Siehe: http://www.simpletest.org/en/web_tester_documentation.html

  • Haben Sie Mut in Ihren Überzeugungen

Der größte Teil der Literatur zu Best Practices der Softwareentwicklung ist Desktop-zentriert / Enterprise App Centric. Während Ihre Website durcheinander ist, lesen Sie diese Bücher und Sie können Ehrfurcht vor der Weisheit haben, die von ihnen ausgeht. Vergessen Sie jedoch nicht, dass die meisten dieser Best Practices in Zeiten entstanden sind, bevor das Web / SEO wichtig wurde. Sie wissen viel über das moderne Web, mehr als in klassischen Büchern wie POEA, Gof usw. erwähnt. Es gibt viel zu entnehmen, aber verwerfen Sie Ihre eigenen Erfahrungen und Kenntnisse nicht vollständig.


Ich könnte weitermachen Aber das sind einige Dinge, die ich ausgewählt habe, als ich eine alte Legacy-Site in eine glänzende neue umgestaltet habe.

JW01
quelle
Gute Referenzlinks!
Nilesh
2

Bevor Sie etwas unternehmen, sollten Sie Ihr Projekt in der Quellcodeverwaltung haben. Auf diese Weise können Sie Änderungen rückgängig machen oder wichtige Änderungen in einem separaten Zweig bearbeiten sowie Meilensteine ​​markieren.

Schreiben Sie als Nächstes Tests für jeden Code, den Sie ändern möchten. Sie müssen nicht alles auf einmal tun und Tests für alles schreiben. Genau das, woran Sie sofort arbeiten möchten. Die Theorie besagt, dass bei genügend Zeit der größte Teil der Codebasis durch Tests abgedeckt wird. Beachten Sie, dass einige Refactorings ohne Tests "sicher" sind - diese sind im zuvor erwähnten Legacy Code- Buch dokumentiert und zweifellos an anderer Stelle.

Ändern Sie den Code, wenn Tests für einen Codeabschnitt vorhanden sind. Tun Sie alles, was Sie brauchen, solange die Tests noch bestehen.

Selbst mit Legacy-Code können Sie TDD ausführen, wenn Sie Ergänzungen oder Änderungen vornehmen. Schreiben Sie einfach zuerst Tests für Ihre erwarteten Änderungen, sehen Sie, dass sie fehlschlagen, und nehmen Sie dann die Änderungen vor.

Einige Tools können hier hilfreich sein. NDepend kann auf stark gekoppelten Code und andere Gerüche hinweisen. NCover verfolgt Ihre Codeabdeckung. FxCop ist im Wesentlichen ein Code-Korrektheitsprüfer, der über das hinausgeht, was der Compiler tut. Dies sind alles nützliche Werkzeuge, die Sie für ein Projekt jeder realen Größe zur Hand haben können, insbesondere für die Legacy-Variante.

Letztendlich ist es ein mehrstufiger Prozess. Versuchen Sie nicht, alles auf einmal zu tun, sondern nehmen Sie es nur ein bisschen nach dem anderen.

Grant Palin
quelle
-2

Wenn es hässlich genug ist, um mich wütend zu machen, ist es hässlich genug, dass ich das Ganze lösche und einen Ersatztropfen schreibe.

Sie werden feststellen, dass dies meistens genauso lange dauert, wie wenn Sie dort sitzen und sich um ein unorganisiertes und undokumentiertes Durcheinander drehen und es sanft streicheln.

Hinterhältigkeit
quelle
2
Ich bin anderer Meinung (obwohl ich dir nicht -1 gegeben habe). joelonsoftware.com/articles/fog0000000069.html
JW01
1
Es ist wirklich eine zu situative Entscheidung, mich genau zu verteidigen. Ich mache das möglicherweise nicht, wenn ich an einer umfangreichen Objective-C-Bibliothek arbeite. Ich habe jedoch keine Bedenken, eine völlig neue Javascript-Bibliothek zu schreiben.
Sneakyness
Sehr schlechte Idee! Ich wünschte, ich hätte den Artikel von Joel Spolsky gelesen, den @ JW01 vor 2 Jahren verlinkt hat, bevor ich mich entschied, eine vorhandene PHP-App mit Angular & Bootstrap neu zu schreiben. Angular & Bootstrap sind großartige Technologien, aber ich versuche 2 Jahre später immer noch, diese alte App zu konvertieren. Ich hätte einfach die vorhandene App ändern und nicht herausreißen / ersetzen sollen.
Zack Macomber
Ich stimme besonders zu, wenn ich Ihren Kommentar berücksichtige. "Szenario" ist der Schlüssel, der eine Entscheidung bestimmt. Sollten Sie diese riesige API herausreißen, die Ihrem gesamten Unternehmen dient? Wer weiß, es gibt viel zu beachten. Sie möchten Tests vorher, um danach zu testen. Der Artikel, auf den verwiesen wird, ist zu linear, als gäbe es eine Einheitsgröße, aber was ist, wenn etwas fehlerhaft ist oder wirklich alter Code? Schlägt der Artikel wirklich vor, dass wir nicht mit Legacy von Code fortfahren, der neuer ist und leichter zu lesen und zu warten ist? Es gibt kein Schwarz-Weiß in der Entwicklerwelt, nur Szenarien und Entscheidungen
James