Wie finde ich in einer alten Codebasis schnell heraus, was verwendet wird und was nicht?

21

Ich wurde gebeten, eine wesentliche ältere Codebasis zu bewerten, um einen Vertrag zur Aufrechterhaltung dieser Codebasis abzuschließen.

Dies ist nicht das erste Mal, dass ich in dieser Situation bin. Im vorliegenden Fall handelt es sich um einen Code für eine relativ hochkarätige und ziemlich gut ausgelastete Multiplayer-Spieleseite, die mindestens mehrere tausend Spieler gleichzeitig online unterstützt. Wie viele solcher Sites ist auch diese eine Mischung aus Front-End- und Back-End-Technologien.

Die Site-Struktur von innen nach außen ist ein Chaos. Überall liegen Ordner mit den Suffixen "_OLD" und "_DELETE". Viele der Ordner scheinen keinen Zweck zu erfüllen oder haben sehr kryptische Namen. Es können beliebig viele alte, nicht verwendete Skripte in legitim aussehenden Ordnern herumliegen. Darüber hinaus gibt es zweifellos viele nicht mehr funktionierende Codeabschnitte, selbst in ansonsten funktionsfähigen Skripten (ein weitaus weniger dringendes Problem).

Dies ist eine Übergabe der etablierten Betreuer an die ursprünglichen Entwickler / Betreuer der Site. Wie in solchen Szenarien verständlicherweise üblich, möchte der etablierte Betreiber mit der Übergabe nur das zu tun haben, was von ihm vertraglich und rechtlich vorgeschrieben ist, um sie an den neu gewählten Betreuer weiterzuleiten. Es kommt also nicht in Frage, Informationen über die vorhandene Site-Struktur aus dem etablierten Unternehmen zu extrahieren.

Der einzige Ansatz, der mir einfällt, um in die Codebasis zu gelangen, besteht darin, im Stammverzeichnis der Site zu beginnen und langsam, aber sicher durch verknüpfte Skripte zu navigieren. Wahrscheinlich werden Hunderte verwendet, Hunderte weitere jedoch nicht. Da sich ein erheblicher Teil der Website in Flash befindet, ist dies noch unkomplizierter, da Verknüpfungen zu anderen Skripten, insbesondere in älteren Flash-Anwendungen, möglicherweise in Binärdateien (.FLAs) und nicht in Textdateien (.AS / ActionScript) eingebettet sind.

Ich frage mich daher, ob jemand bessere Vorschläge dazu hat, wie die gesamte Codebasis auf Wartbarkeit überprüft werden kann. Es wäre wunderbar, wenn es eine Möglichkeit gäbe, ein Diagramm der Zugriffshäufigkeit auf Dateien auf dem Betriebssystem des Webservers (auf das ich Zugriff habe) anzuzeigen, da dies möglicherweise einen Einblick in die wichtigsten Dateien bietet, auch wenn dies nicht der Fall ist in der Lage sein, jene Dateien zu eliminieren, die niemals verwendet werden (da einige Dateien nur einmal im Jahr verwendet werden könnten).

Ingenieur
quelle
7
Ich weiß nicht genug über Flash, aber wenn Kompilierungsfehler auftreten, wenn kein Code vorhanden ist, sollten Sie Ordner umbenennen können, um festzustellen, ob auf sie verwiesen wird.
Oded
Schlechte Lösung: Löschen Sie sie und warten Sie auf die Fehlerberichte. (
Stellen
1
@Nick Könnten Sie klären, ob Sie für die Bewertung im Rahmen der nächsten Vertragsphase bezahlt werden, auf die Sie noch bieten müssen / die Sie anderweitig erhalten? Ihre Antwort ändert nichts an der Frage "Gibt es ein Werkzeug?", Aber einige von uns könnten Antworten für einen Prozess finden, der besser zu Ihrer Situation passt (z. B. verhindern, dass Sie verarscht werden usw.).
Jcmeloni
@jcmeloni Nein, ich werde nicht für die Bewertung bezahlt. Aber meiner Erfahrung nach und aufgrund von kleinen Dingen, die ich in den letzten Tagen aufgegriffen habe, haben sie im Moment niemanden am Tisch. Meine Fähigkeiten sind ziemlich ungewöhnlich, deshalb bin ich umso entspannter, als sie niemanden haben, der nach dem Zitat darum konkurriert. Das fragliche Angebot stammt von meinem zukünftigen Kunden, der plant, ihm den Auftrag erneut zu erteilen. Wirklich von meinem Ende, soll ich ihnen helfen , besagtes Zitat zur Verfügung zu stellen. HTH.
Ingenieur
@Oded Rename ist definitiv einfacher als das Löschen durch Ausprobieren! Gutes Denken dort. Das ist ein weiteres Werkzeug in der Box.
Ingenieur

Antworten:

32

Da das, was Sie gefragt werden , Wesen zu tun ist , Eingang sorgen für Ihre Kunden einen entsprechenden Vorschlag an die schreiben andere Auftraggeber (Inhaber-of-the-Albtraum-Code) für alle Arbeiten an diesem Code, werde ich gehen auf ein Glied und sagen, dass Sie zu diesem Zeitpunkt keine gründlichen Tests oder Umgestaltungen oder ähnliches durchführen werden. Sie haben wahrscheinlich eine sehr kurze Zeit, um eine grobe Schätzung zu erhalten. Meine Antwort basiert auf meinen Erfahrungen in der gleichen Situation. Wenn meine Interpretation falsch ist, ignorieren Sie einfach alles, was folgt.

  • Verwenden Sie ein Spidering-Tool, um ein Gefühl dafür zu bekommen, welche Seiten vorhanden sind und was eingehend ist. Sogar ein einfaches Linkchecker-Tool - kein spezielles "Spider for Auditing" -Tool - wird in dieser Hinsicht nützlich sein.
  • Erstellen Sie eine einfache Audit- / Inventar-Tabelle. Dies kann so einfach sein wie eine Liste von Dateien und ihre zuletzt geänderte Zeit, geordnet nach Verzeichnissen. Dies wird Ihnen helfen, ein Gefühl für den Umfang zu bekommen, und wenn Sie zu Verzeichnissen wie _OLD und _DELETE gelangen, können Sie eine große Anmerkung machen, dass a) Ihre Bewertung auf Dingen basiert, die sich nicht in diesen Verzeichnissen befinden, b) das Vorhandensein dieser Verzeichnisse und das Potenzial für cruft / hidden nightmares zeugen von tieferen Problemen , die in irgendeiner Weise im Angebot Ihres Kunden berücksichtigt werden sollten . Sie müssen nicht viele Jahre damit verbringen, die möglichen Probleme in _OLD oder _DELETE aufzuzählen. Die Informationen fließen in das endgültige Gebot ein.
  • Wenn Sie sich überlegen, was sich wie eine vollständig webbasierte App anhört, werden auch Standard-Tools zur Protokollanalyse Ihr Freund sein. Sie können dem Arbeitsblatt einen Eindruck von "Dies ist in den Top 10 der Skripte, auf die zugegriffen wird" oder dergleichen hinzufügen. Auch wenn die Skripte in Flash-Dateien eingebettet und daher nicht spiderbar sind, besteht eine hohe Wahrscheinlichkeit, dass sie über POST oder GET aufgerufen werden und in den Serverprotokollen angezeigt werden. Wenn Sie wissen, dass Sie 10 Skripte haben, auf die häufig zugegriffen wird, und nicht 100 (oder umgekehrt), erhalten Sie eine gute Vorstellung davon, wie die Wartungsarbeiten wahrscheinlich verlaufen werden.

Selbst in einer komplizierten Site ist das, was ich oben skizziert habe, etwas, was Sie in anderthalb Tagen tun können. Da die Antwort, die Sie Ihrem Klienten geben werden, ungefähr so ​​lautet: "Dies wird ein ungeheurer Schmerz für den Hintern sein, und hier sind einige Gründe, warum Sie einem Schwein nur Lippenstift geben, und Sie sollten dementsprechend bieten "oder" jede vernünftige Person würde bieten, nicht zu warten, sondern von vorne zu beginnen, also sollten Sie entsprechend bieten "oder sogar" das ist nicht so schlimm, aber es wird ein beständiger Arbeitsfluss über einen bestimmten Zeitraum sein, also bieten Sie entsprechend " Der Punkt ist, dass sie das Gebot abgeben werden und Sie daher nicht so genau sein müssen, wie Sie es wären, wenn Sie direkt beauftragt würden, eine vollständige Prüfung des Inhalts und der Architektur durchzuführen.

jcmeloni
quelle
2
+1 Das ist eine fantastische Antwort. Wo ist dieser +5 Knopf hingekommen ...
Ingenieur
1
TL; DR: Schick dich nicht in ein Kaninchenbau, bis du musst. :)
jcmeloni
4

Ich empfehle dringend, den vorhandenen Quellcode (im Gegensatz zu einem Umschreiben) mithilfe der Muster aus dem Buch " Effektiv mit Legacy-Code arbeiten " umzugestalten .

In diesem Buch werden verschiedene Mechanismen beschrieben, mit denen Sie in Komponententests Legacy-Code effizient abdecken können, damit Sie den Code sicher umgestalten können. Das Buch besteht aus Teilen, von denen eines die Philosophie des Ansatzes beschreibt, und mehreren Kapiteln, die bestimmte Probleme lösen, wie "Es dauert ewig, eine Änderung vorzunehmen", "Ich habe nicht viel Zeit und muss sie ändern" und "Ich kann diese Klasse nicht in ein Testgeschirr einbinden". In jedem dieser Kapitel finden Sie ausführliche, bewährte Techniken, mit denen Sie lernen, wie Sie bewährte Testmethoden auf Probleme in der Praxis anwenden können.

Beim Lesen des Buches hatte ich das Gefühl, dass "wir nicht allein sind" ... viele von uns oder vielleicht alle von uns arbeiten mit komplexen Codebasen, die schwierig zu verwalten sind. Die im Buch aufgeführten Techniken haben mir viel Hoffnung gegeben, und ich habe sie fast sofort persönlich anwenden können.

Joel Spolskys Blog-Post erklärt hervorragend, warum es am besten ist, eine bestehende, funktionierende Codebasis beizubehalten, anstatt von vorne zu beginnen. Ich habe ein Zitat aus dem Artikel ausgewählt, das es zusammenfasst, aber es ist eine fantastische Lektüre.

"Es gibt einen subtilen Grund, warum Programmierer den Code immer wegwerfen und von vorne anfangen wollen. Der Grund ist, dass sie den alten Code für ein Durcheinander halten. Und hier ist die interessante Beobachtung: Sie liegen wahrscheinlich falsch. Der Grund, warum sie den alten denken Code ist ein Durcheinander, das auf ein grundlegendes Kardinalgesetz der Programmierung zurückzuführen ist:

Es ist schwieriger, Code zu lesen, als ihn zu schreiben. "- http://www.joelonsoftware.com/articles/fog0000000069.html

Kyle Hodgson
quelle
4
+1. Als Antwort auf Joels Kommentar: "Es sollte verdammt noch mal nicht gut sein." Weil ich das Problem nicht als inhärent sehe. Ich sehe es teilweise als die Tatsache, dass viele Leute schlampigen Code schreiben und sich nicht darum kümmern, während viele andere einigermaßen guten Code schreiben, aber nach dem "selbstdokumentierenden Code" -Konzept leben ... das ist einfach nur BS: Man mag schmeicheln Der eigene Codierungsstil lässt keine Wünsche offen, aber wenn es um öffentliche Codebasen geht, laichen Sie einfach Kommentare, als gäbe es kein Morgen. Tut nicht weh Und schließlich gibt es Leute, die Dinge in einer alten Codebasis zum Laufen bringen müssen, mit einem engen Zeitbudget.
Ingenieur
2

In einer typischen Java-Codebasis werde ich Tools wie PMD, FindBugs oder Sonar verwenden und dann versuchen, die Berichterstellung für Tools zu verstehen (toter Code, undokumentierter Code, duplizierter Code usw.).

Basierend auf den Berichten werde ich versuchen, die verschiedenen Schichten der Anwendung / Site (Business-Schicht, DB, SQL usw.) zu finden.

Wenn Ebenen gekoppelt sind (HTML innerhalb des Servlets, SQL innerhalb des Java-Codes), beginne ich mit dem Entkoppeln. Jeder dieser Schritte sollte als isoliert betrachtet werden. Sie können am Ende jeder einzelnen einen Commit ausführen (indem Sie eine Verzweigung starten und dann die Zusammenführung durchführen). .

Abderrazak BOUADMA
quelle
1
Vielen Dank. Obwohl Ihre Antwort etwas Java-spezifisch ist, ist es interessant zu sehen, wie vielschichtig Sie vorgehen ... sozusagen die Zwiebel schälen. Etwas zum Nachdenken.
Ingenieur
1

Aus Ihrer Beschreibung geht hervor, dass dieser Code den Status "Nicht verwaltbar" erreicht hat, was bedeutet, dass der beste Ansatz wahrscheinlich ein vollständiges Umschreiben ist. Entwickler hätten viel kleinere Gehaltsschecks, wenn es Qualitätswerkzeuge gäbe, die dafür sorgen würden, dass eine unordentliche Codebasis gewartet werden kann. Es ist möglich, den alten, nicht benötigten Code aus Ordnern zu entfernen, aber es ist eine manuelle Aufgabe, und Sie werden wahrscheinlich sowieso nicht alles ohne unzumutbare Zeit erhalten. Ich rate hier nur, aber ich wette, der Arbeitscode selbst ist genauso verwirrend wie die Dateistruktur. Selbst wenn Sie es schaffen, die Codebasis auf den aktiv arbeitenden Code zu reduzieren, wird dies immer noch ein Albtraum sein etwas zu aktualisieren oder zu beheben.

Ich möchte betonen, dass der Aufwand, der erforderlich ist, um den vorhandenen Code in einen wartbaren Zustand zu versetzen, gleich oder größer ist als der Aufwand, bei einem Neuschreiben von vorne zu beginnen. Ein Teil der Instandhaltung besteht darin, zu wissen, wann "es hinter den Schuppen gebracht und erschossen werden muss".

Ryathal
quelle
Normalerweise bin ich zu 100% bei Ihnen, wenn es um das Werfen und Umschreiben geht. Aber in diesem Fall (und zumindest im Moment) muss ich dafür bezahlen, dass ich nur für die Wartung der Website arbeite, und nicht für eine umfassendere Überholung, die mehrere Wochen in Anspruch nehmen würde. Auch wenn ich gerade jetzt wollte, konnte ich das nicht mithalten und die anderen Verträge, die ich unterwegs habe, niederhalten, da meine wöchentliche Verfügbarkeit hierfür ausdrücklich begrenzt ist - mein Hauptvertrag muss bis zu seinem Ablauf erfüllt werden Mindestens 40 Stunden pro Woche.
Ingenieur
1
Nicht einverstanden mit werfen und neu schreiben! Aus joelonsoftware.com/articles/fog0000000069.html ... "Es gibt einen subtilen Grund, warum Programmierer den Code immer wegwerfen und von vorne anfangen möchten. Der Grund ist, dass sie den alten Code für ein Durcheinander halten. Und hier ist die interessante Beobachtung : Sie liegen wahrscheinlich falsch. Der Grund, warum sie den alten Code für ein Chaos halten, liegt in einem grundlegenden Kardinalgesetz der Programmierung: Es ist schwieriger, Code zu lesen, als ihn zu schreiben. " Stattdessen empfehle ich dringend die Umgestaltung: amazon.ca/Working-Effective-Legacy-Michael-Feathers/dp/…
Kyle Hodgson
1
@KyleHodgson Manchmal ist der Code tatsächlich ein Durcheinander, und wenn Sie an dem Punkt angelangt sind, an dem es ein Durcheinander ist, den Code vor dem Lesen zu finden, ist es an der Zeit, von vorne zu beginnen.
Ryathal
Ja, ich glaube nicht, dass es so eindeutig ist, obwohl das Buch lesenswert aussieht. Es hängt sehr stark von der Größe / Komplexität der Codebasis und den warmen Körpern ab, die für die Arbeit zur Verfügung stehen.
Ingenieur
1

Mithilfe eines Webcrawlers können Sie möglicherweise ermitteln, auf welche URLs zugegriffen werden kann. Vor allem, wenn es intelligent genug ist, um Links aus Flash oder JavaScript zu extrahieren. Wenn Sie eine Liste von Webseiten haben, gehen Sie diese durch und listen Sie die Dateien auf, auf die sie verweisen. Alles, was nach diesem Vorgang übrig bleibt, sollte als toter Code betrachtet werden.

Mike Baranczak
quelle
1
Ich stimme Ihrem letzten Satz überhaupt nicht zu. Crawler kann nur feststellen, welche Seiten als gerichteter Graph mit einem oder mehreren Startpunkten miteinander verknüpft sind. Wenn wir aber von einer Website sprechen, gibt es auch so genannte "Landing Pages", die auf andere Seiten verweisen, auf die jedoch keine Links verweisen. Möglicherweise gibt es auch alte Teile der Verwaltungsoberfläche, die nicht mehr mit anderen Seiten verbunden sind. Ich habe derzeit ein Projekt dieser Art.
Drehbuch
0

Hinweis: Ich habe einen Akzent auf die Datenbanknutzung gelegt, während Sie nach der Verwendung des Codes selbst gefragt haben. Die Antwort gilt immer noch für beide Fälle in jedem Punkt, den ich erwähnt habe.

Sie haben im letzten Absatz zum Teil bereits Ihre eigene Frage beantwortet: Sehen Sie, worauf zugegriffen wird, während die Anwendung ausgeführt wird.

  1. Möglicherweise möchten Sie die Datenbank profilieren und den Profiler bitten, alle Abfragen für einen Tag aufzuzeichnen. Sie erhalten einen Überblick über die am häufigsten verwendeten Datenbankobjekte, können jedoch nicht feststellen, welche Objekte niemals verwendet werden. Außerdem müssen Sie mit den Ergebnissen immer noch vorsichtig sein: Beispielsweise kann eine Tabelle ausschließlich über gespeicherte Prozeduren verwendet werden. Wenn Sie sich jedoch die Abfragen des Profilers ansehen, sieht es so aus, als würde die Tabelle überhaupt nicht verwendet.

  2. Das Überprüfen des Quellcodes und das Suchen nach Abfragen ist hilfreicher. Nachdem Sie alle Abfragen gesammelt haben, können Sie die Datenbanknutzung besser verstehen, und zwar nicht in Bezug auf die Häufigkeit (hier ist ein Profiler praktisch), sondern in Bezug auf die Verwendung / Nicht-Verwendung gebrauchte Tische. Leider kann es für eine seit Jahren schlecht geschriebene / nicht gewartete Codebasis äußerst schwierig und fehleranfällig sein , insbesondere wenn Abfragen dynamisch erstellt werden (stellen Sie sich eine Methode vor, die in a selecteinen Parameter als Namen für die Tabelle verwendet; wie können Sie dies tun?) möglicherweise wissen, was die möglichen Werte des Parameters sind, indem Sie nur den Quellcode betrachten?).

  3. Statische Analyse und einige Compiler zeigen möglicherweise auch toten Code, geben Ihnen jedoch immer noch nicht die gewünschte Antwort.

  4. Die Analyse der Daten selbst oder der Datenbankmetadaten kann einige interessante Informationen liefern . Zum Beispiel wäre es leicht zu behaupten, dass die Tabelle LogonAudit(uniqueidentifier LogonAuditId, datetime LogonEvent, ...)nicht mehr verwendet wird , wenn es 10 000 Datensätze pro Tag enthält für die Jahre 2006 bis 2009 und keine Aufzeichnungen von September, 18 th 2009. Das gleiche gilt für ein nicht wahr Tabelle, die die Daten enthält, die zum größten Teil schreibgeschützt sind.

Diese vier Punkte zusammen ergeben die Liste der verwendeten Tabellen. Verbleibende werden entweder verwendet oder nicht. Sie können Behauptungen aufstellen und sie testen, aber ohne eine gute Abdeckung durch Unit-Tests wäre dies nicht einfach. Jeder "einfache" Weg würde auch scheitern. Wenn Sie beispielsweise eine products_delme_not_usedTabelle haben, können Sie behaupten, dass die Tabelle überhaupt nicht verwendet wird, und in Ihrem Code nach "products_delme_not_used" suchen. Dies ist optimistisch: Es ist nicht ungewöhnlich, den DailyWTF-Kandidaten in einer alten Codebasis wie folgt zu finden:

// Warning: WTF code below. Read with caution, never reuse it, and don't trust
// the comments.

private IEnumerable<Product> GetProducts()
{
    // Get all the products.
    return this.GetEntities<Product>("PRODUCT");
}

private IEnumerable<T> GetEntities<T>(string tableName)
{
    // Everyone knows that SQL is case sensitive.
    tableName = tableName.ToLower();

    if (tableName == "user" || tableName == "product")
    {
        // Those tables were renamed recently in the database. Don't have time
        // to refactor the code to change the names everywhere.
        // TODO: refactor the code and remove this `if` block.
        tableName += "s";
    }

    if (this.IsDelme(tableName))
    {
        // We have some tables which are marked for deletion but are still
        // used, so we adjust their name.
        tableName = this.Delme(tableName);
    }

    return this.DoSelectQuery<T>("select top 200 * from " + tableName);
}

private bool IsDelme(string name)
{
    // Find if the table is among candidates for removal.
    List<string> names = this.Query<string>("select Names from DelmeTables");
    return names.Contains(name);
}

private string Delme(string name)
{
    // Return the new name for a table renamed for deletion.
    return string.Join("_", new [] { name, "delme", "not", "used" });
}

Können Sie herausfinden, dass dieser Code tatsächlich eine products_delme_not_usedTabelle verwendet?

Wenn ich du wäre, würde ich:

  1. Halten Sie alle Datenbankobjekte an Ort und Stelle,
  2. Refactor die gesamte Anwendung (wenn es sich lohnt),
  3. Dokumentieren Sie (während des Refactorings) die Anwendung und insbesondere die Datenbanknutzung.

Wenn Sie die letzten beiden Schritte abgeschlossen haben, haben Sie wahrscheinlich ein besseres Verständnis für die Datenbanknutzung. Dadurch können Sie die Namen der Tabellen ermitteln, die nicht mehr verwendet werden, und sie möglicherweise mehr oder weniger sicher entfernen.

Arseni Mourzenko
quelle
0

Für mich scheint es, dass Sie genügend Informationen benötigen, um ein Angebot zu erstellen, damit ich mich auf diese Bemühungen konzentrieren kann.

Ich würde versuchen, festzustellen, wie viele Anwendungsfälle auf dieser Site vorliegen. Auf diese Weise erhalten Sie normalerweise eine Vorstellung davon, wie groß und kompliziert die Site ist und wie lange es dauern wird, die Site / Anwendung neu zu erstellen oder zu verwalten.

Ja, es stimmt, dass Code manchmal nicht mehr verwendet wird und die Anwendung dadurch ein bisschen größer aussieht als sie wirklich ist, aber ich glaube nicht, dass dies die Zahlen um mehr als 20% beeinflussen wird Also würde ich mir keine Sorgen um diesen Teil machen.

Wenn Sie sich den Quellcode ansehen, sollten Ihnen Webseiten und Datenbanktabellen dabei helfen, dies herauszufinden.

Möglicherweise möchten Sie auch die Anzahl der Stunden pro Monat begrenzen, die Sie für dieses Projekt ausgeben, um sich selbst zu schützen.

Es gibt keinen einfachen Weg, um herauszufinden, was verwendet und was nicht. Tools für die Codeanalyse können hilfreich sein, aber da Sie es mit einem so gemischten Problem zu tun haben, gibt es meines Erachtens kein einziges Tool, das Abhilfe schafft. Für jeden spezifischen Bereich finden Sie wahrscheinlich ein Code-Analyse-Tool, das möglicherweise hilfreich ist.

Sarel Botha
quelle