Ich habe das Buch "Effektiv mit Legacy-Code arbeiten" einige Male empfohlen. Was sind die wichtigsten Punkte dieses Buches?
Gibt es viel mehr, um mit altem Code umzugehen, als Unit- / Integrationstests hinzuzufügen und dann umzugestalten?
Ich habe das Buch "Effektiv mit Legacy-Code arbeiten" einige Male empfohlen. Was sind die wichtigsten Punkte dieses Buches?
Gibt es viel mehr, um mit altem Code umzugehen, als Unit- / Integrationstests hinzuzufügen und dann umzugestalten?
Antworten:
Das Hauptproblem mit Legacy-Code ist, dass es keine Tests gibt. Sie müssen also einige hinzufügen (und dann noch mehr ...).
Dies an sich würde, wie @mattnz feststellte, eine Menge Arbeit kosten. Aber das besondere Problem des Legacy - Code ist , dass es nie testbar wurde entwickelt . In der Regel handelt es sich also um ein gewaltiges Durcheinander von Spaghetti-Code, bei dem es sehr schwierig oder gar nicht möglich ist, zu prüfende Kleinteile zu isolieren. Daher müssen Sie den Code vor dem Unit-Test überarbeiten , um ihn testbarer zu machen.
Um jedoch sicher umgestalten zu können, müssen Sie Unit-Tests durchführen, um sicherzustellen, dass Sie mit Ihren Änderungen nichts angestellt haben ... Dies ist der Haken 22 des Legacy-Codes.
Das Buch zeigt Ihnen, wie Sie aus diesem Haken ausbrechen, indem Sie die absolut minimalen und sichersten Änderungen am Code vornehmen, nur um die ersten Komponententests zu ermöglichen. Diese sollen das Design nicht schöner machen, sondern nur Unit-Tests ermöglichen. In der Tat machen sie manchmal das Design hässlicher oder komplexer. Mit ihnen können Sie jedoch Tests schreiben - und sobald Sie Komponententests durchgeführt haben, können Sie das Design verbessern.
Es gibt viele Tricks, um den Code testbar zu machen - einige sind offensichtlich, andere überhaupt nicht. Es gibt Methoden, an die ich niemals gedacht hätte, ohne das Buch zu lesen. Noch wichtiger ist jedoch, dass Feathers erklärt, was eine Code-Einheit genau testbar macht. Sie müssen Abhängigkeiten reduzieren und Barrieren in Ihren Code einführen, jedoch aus zwei verschiedenen Gründen:
Das sichere Trennen von Abhängigkeiten kann schwierig sein. Das Einführen von Interfaces, Mocks und Dependency Injection ist ein sauberes und ansprechendes Ziel, das zu diesem Zeitpunkt jedoch nicht unbedingt sicher ist. Daher müssen wir manchmal auf die Unterklasse der getesteten Klasse zurückgreifen, um eine Methode zu überschreiben, die normalerweise z. B. eine direkte Anforderung an einen DB startet. In anderen Fällen müssen wir möglicherweise sogar eine Abhängigkeitsklasse / jar in der Testumgebung durch eine gefälschte ersetzen ...
Das wichtigste Konzept von Feathers sind für mich die Nähte . Eine Naht ist eine Stelle im Code, an der Sie das Verhalten Ihres Programms ändern können, ohne den Code selbst zu ändern . Nähte in Ihr Code - Aufbau ermöglicht trennt das Stück im Test befindlichen Code, aber es ermöglicht Ihnen auch zu spüren , das Verhalten des Codes im Test auch dann , wenn es schwierig oder unmöglich ist , direkt zu tun (zB weil der Anruf tätigt Änderungen in einem anderen Objekt oder Subsystem , deren Status nicht direkt aus der Testmethode heraus abgefragt werden kann).
Mit diesem Wissen können Sie die Keime der Testbarkeit im schlimmsten Haufen Code erkennen und die minimalen, am wenigsten störenden und sichersten Änderungen finden, um dahin zu gelangen. Mit anderen Worten, zu vermeiden „offensichtlich“ Refactorings zu machen , die ein Risiko des Brechens des Codes haben , ohne dass Sie es merken - weil Sie nicht noch die Unit - Tests haben , dass zu erkennen.
Schnelle Möglichkeiten, um die wichtigsten Punkte des effektiven Arbeitens mit Legacy-Code zu erreichen
Ich arbeite auf einer Codebasis von Millionen von Codezeilen, von denen einige aus den 1980er Jahren stammen. Es ist nur Software, also müssen Sie nur ein paar Unit-Tests schreiben, damit Sie es überarbeiten und so viel besser machen können.
Das Schlüsselwort hier ist einfach - es ist ein aus vier Buchstaben bestehendes Wort, das zu keinem Programmierer-Vokabular gehört, geschweige denn zu einem, der an Legacy-Systemen arbeitet.
Wie lange dauert es Ihrer Meinung nach, einen Komponententest zu schreiben, um den Entwicklungsaufwand von einer Stunde zu testen? Sagen wir zur Diskussion noch eine Stunde.
Wie viel Zeit wird in dieses 20 Jahre alte Legacy-System mit einer Million Leitungen investiert? Sagen wir 20 Entwickler für 20 Jahre mal 2000 Stunden / Jahr (sie haben ziemlich hart gearbeitet). Lassen Sie uns jetzt eine Zahl auswählen - Sie haben neue Computer und neue Werkzeuge und Sie sind so viel schlauer als die Leute, die dieses Stück von $% ^^ geschrieben haben - sagen wir, Sie sind 10 von ihnen wert. Hast du 40 Mannjahre, oder ...?
Die Antwort auf Ihre Frage lautet also: Es gibt noch viel mehr. Zum Beispiel ist diese Routine, die 1000 Zeilen umfasst (ich habe einige, die über 5000 sind), übermäßig komplex und ein Stück Spaghetti. Es würde nur ein paar Tage dauern (noch ein Wort mit vier Buchstaben), um es in ein paar 100 Zeilen Routinen und ein paar weitere 20 Zeilen Helfer zu zerlegen, oder? FALSCH. In diesen 1000 Zeilen sind 100 Fehlerkorrekturen verborgen, von denen jede eine undokumentierte Benutzeranforderung oder einen dunklen Randfall darstellt. Es sind 1000 Zeilen, weil die ursprüngliche 100-Zeilen-Routine den Job nicht erledigt hat.
Sie müssen mit der Einstellung arbeiten, " wenn es nicht kaputt ist, reparieren Sie es nicht ". Wenn es kaputt ist, müssen Sie sehr vorsichtig sein, wenn Sie es reparieren - während Sie es verbessern, ändern Sie nicht versehentlich etwas anderes. Beachten Sie, dass "pleite" möglicherweise Code enthält, der nicht verwaltbar ist, aber ordnungsgemäß funktioniert. Dies hängt vom System und seiner Verwendung ab. Fragen Sie "Was passiert, wenn ich das vermassle und es noch schlimmer mache?", Denn eines Tages werden Sie dem Chef der Bosse sagen müssen, warum Sie sich dafür entschieden haben.
Diese Systeme können immer besser gemacht werden. Sie haben ein Budget, an dem Sie arbeiten können, einen Zeitplan, was auch immer. Wenn Sie nicht - gehen Sie und machen Sie eine. Hör auf, es besser zu machen, wenn das Geld / die Zeit abgelaufen ist. Fügen Sie ein Feature hinzu, und lassen Sie sich Zeit, um es ein wenig zu verbessern. Beheben Sie einen Fehler - noch einmal, nehmen Sie sich etwas mehr Zeit und verbessern Sie ihn. Liefern Sie es niemals schlechter als zu Beginn.
Es gibt zwei wichtige Punkte, die aus dem Buch entfernt werden sollten.
Wie andere Antwortende bereits betont haben, ist der Versuch, Ihren vorhandenen Legacy-Code vorzeitig zu aktualisieren, ein Kinderspiel . Nehmen Sie sich stattdessen immer dann Zeit, wenn Sie Änderungen am Legacy-Code vornehmen müssen (für eine neue Funktion oder eine Fehlerbehebung), um den Legacy-Status zu entfernen.