Wie kann man ein Projekt ohne Struktur reparieren?

25

Ich arbeite seit über 5 Jahren an einem Software-Projekt, meistens solo. Am Anfang war es ein Durcheinander (ich bin der dritte oder vierte Entwickler, der daran arbeitet), und obwohl es jetzt weniger Durcheinander ist, ist es immer noch unglaublich durcheinander. Die Geschwindigkeit, mit der ich es in den Griff bekomme, ist eiskalt und ich fange an, über den Zustand, in dem es sich befindet, verzweifelt zu sein. Wie fange ich wirklich an, es zu reparieren?

Projektdetails: Es handelt sich um ein Verkaufsprogramm, das fast ausschließlich in Visual Basic Classic (VB6) mit einem MySQL-Back-End und einer in C # geschriebenen Berichts-Engine geschrieben wurde. Es macht Spaß, an dem C # -Modul für die Berichterstellung zu arbeiten. Es wurde erst in den letzten Jahren geschrieben und davor wurden alle Berichte in Crystal Reports 9 erstellt (ja, es gibt noch einige Berichte, die darauf basieren).

Das eigentliche Programm selbst ist jedoch eine völlige Katastrophe. Es gibt nicht ganz 90.000 LOC insgesamt und etwa 10.000 Kommentarzeilen (meist keine Dokumentation, aber alten Code, der auskommentiert wurde). 158 Formulardateien und 80 Moduldateien. Ich habe keine Ahnung, wie viele davon tatsächlich verwendet werden, da einige Funktionen des Programms einfach veraltet sind und (äh, manchmal) als solche gekennzeichnet sind, ohne dass der zugehörige Code aus dem Programm entfernt wurde. Ich würde vermuten, dass nur 50% des Codes tatsächlich produktiv genutzt werden.

Ich habe Angst, einen Großteil des Codes zu berühren, nur weil ich nicht sicher bin, ob ich etwas kaputt mache, auf das sich ein undurchsichtiger Client verlässt. Das passiert öfter, als ich zählen kann. Es ist, als ob im Code Landminen verstreut sind.

Das Projekt ist nicht wirklich strukturiert. Es ist nicht objektorientiert, außer an den wenigen Stellen, an denen ich die Geduld hatte, mich zu reformieren. Wenn Sie Daten in einem Formular abrufen müssen, instanziieren Sie ein Datenbankobjekt, deklarieren Ihre Abfrage direkt in der Funktion, führen Sie sie aus und führen Sie die gewünschten Schritte mit dem Datensatz aus.

Als ich anfing, an dem Projekt zu arbeiten, wurde keine Quellcodeverwaltung verwendet. Ich versuchte, die anderen Leute, an denen ich arbeitete, zu ermutigen, es zu benutzen, aber ich war der neue Typ und meine Versuche, die Leute dazu zu bringen, Subversion zu benutzen, scheiterten so gut wie. Der leitende Entwickler des Unternehmens hat in den letzten Jahren endlich einen Quecksilberfehler bekommen und er hat dafür gesorgt, dass alle Entwickler jetzt bei allen Projekten die Quellcodeverwaltung verwenden, zumindest ist dies ein Fortschritt.

Ich denke, wenn ich in der Lage wäre, das Projekt in Vollzeit zu reformieren, wäre ich in der Lage, angemessene Fortschritte zu erzielen und vielleicht sogar eine Schätzung darüber zu haben, wie lange es dauern würde, das Projekt vollständig zu überarbeiten, aber es wird aktiv genutzt und ich bin es ständig gebeten werden, Feuer zu löschen, Fehler zu beheben, Funktionen hinzuzufügen usw. usw.

Wie kann ich dieses Projekt wirklich reparieren? Versuchen Sie, VB6 mit einer anderen Sprache zu bearbeiten? Versuchen Sie, das Programm in meiner Freizeit neu zu schreiben? Oder ist das völlig hoffnungslos?

Aktualisieren

Nach diesem Beitrag kehrte ich mit neuem Eifer zum Projekt zurück, fiel aber innerhalb weniger Monate in die Hoffnungslosigkeit zurück, nachdem ich eine so langsame Fortschrittsrate festgestellt hatte. Ich habe diesen Zyklus dann im nächsten Jahr noch zwei- oder dreimal wiederholt.

Ich bin seitdem zu einem anderen Job übergegangen. Obwohl nach so vielen Jahren von vb6 und nur peripheren Erfahrungen mit anderen Technologien die Suche schwierig war und ich unterwegs mit vielen Ablehnungen konfrontiert war (ungefähr ein Dutzend Interviews im Laufe eines Jahres). Mein Rat an andere in dieser Situation ist, in Betracht zu ziehen, diesen Faktor in Ruhe zu lassen. Bedenken Sie, welchen Schaden Sie Ihrer Karriere zufügen können, wenn Sie in einer solchen Sackgasse bleiben.

Dylan Nissley
quelle
4
Hört sich ziemlich schlecht an. Ein Anfang wäre, eine Kopie des aktuellen Codes zu speichern und den alten Code zu entfernen, der auskommentiert wurde (das ist nur Rauschen). Wenn ich an einem Legacy-System arbeitete, setzte ich normalerweise ein Datum an die Spitze des Codes, den ich auskommentierte. Dann kommentierte gut out Code aus, der 6 Monate alt oder älter war.
Programmierer
4
Ich würde mit Jamison anfangen und mich durch das Regal arbeiten. . .
Wyatt Barnett
1
Haben Sie jemals versucht, ein C # -Projekt zu übernehmen, das von einem VB-Programmierer geschrieben wurde?
שישתיא אבישגנת

Antworten:

28

Jetzt, da es sich in der Quellcodeverwaltung befindet, können Sie den auskommentierten Code entfernen.

Ich habe hier in einer ähnlichen Situation angefangen (80KLOC VB6-App ohne Quellcodeverwaltung, ohne echte Struktur, fast alles, was in Event-Handlern gemacht wurde).

In ungefähr zwei Jahren habe ich mehr als die Hälfte auf C # umgestellt (normalerweise, wenn wichtige neue Funktionen erforderlich sind). Der gesamte neue C # -Code deckt Unit-Tests ab. Die Konvertierung nach C # nimmt jedoch definitiv viel mehr Zeit in Anspruch. Wenn Sie keine bedeutenden neuen Module hinzufügen, würde ich diesen Weg nicht beschreiten.

Ich habe eine rudimentäre Datenzugriffsebene erstellt, die sich automatisch aus der Datenbank generiert hat. Das hatte zumindest Probleme, als sich der Name einer Tabellenspalte änderte und ich nicht alle Stellen im Code fand. Außerdem habe ich die Geschäftslogik langsam aus den Formularereignishandlern in Module verschoben.

Ich hatte jedoch den Vorteil, dass die Bewerbung nur intern war. Da ich nur einen Standort zum Bereitstellen hatte, konnte ich größere Risiken eingehen als Sie. Wenn ich einen Fehler gemacht habe, war es normalerweise keine große Sache, ihn zu beheben. Klingt so, als hättest du diesen Luxus nicht.

Ich denke wirklich, dass Ihre beste Wette darin besteht, den folgenden Ansatz zu verfolgen:

  1. Erfahren Sie alles bis ins kleinste Detail. Dadurch ist es weniger wahrscheinlich, dass Sie versehentlich etwas kaputt machen.
  2. Refactor gnadenlos, um Trennung und Struktur zu verbessern, aber versuchen Sie nicht, eine neue Methodik wie objektorientiertes Programmieren in sich aufzunehmen, da VB6 einfach nur nervt.
  3. Behandle es als eine Lernerfahrung. Wie würdest du wissen, dass ein anderer Weg besser ist, wenn du den minderwertigen Weg nie gesehen hättest?
  4. Machen Sie sich nicht die Mühe, in einer neuen Sprache / einem neuen Framework / einer neuen Plattform umzuschreiben, es sei denn, Sie müssen ein Hauptmodul schreiben. Auch dann überlegen Sie genau.

Denken Sie daran, das Ziel des Programms ist es, ein Produkt zu sein, mit dem Ihr Unternehmen Geld verdient. Es muss kein einwandfreies Kunstwerk sein (und ich bin ein Perfektionist, deshalb fällt es mir wirklich schwer, das zuzugeben). Manchmal ist es besser, sich auf Pragmatismus einzulassen.

Es gibt angeblich eine Menge von COBOL-Programmierern, die riesige Mengen an Legacy-Code verwalten. Ich bezweifle, dass sie alle fleißig daran arbeiten, es in einer neuen Sprache umzuschreiben. :)

Scott Whitlock
quelle
3
+1 Tolle Antwort: Ich kann nur hinzufügen, dass Sie nicht zu viel Erwartung an sich selbst haben. Die Codewartung ist langsam im Vergleich zu Neuentwicklungen, Legacy-Code, noch langsamerem und undokumentiertem, unstrukturiertem Code, wie Sie ihn beschrieben haben SLOC ... Ich kenne deine Schmerzen ...
Mattnz
+1, aber ein OO-Merkmal, das VB6 in Ordnung macht, ist Schnittstellen. Wenn Sie einige Male ähnliche codierte Kopien und Pasten sehen, können Sie möglicherweise eine Umgestaltung in einem Interface durchführen, wenn nicht in einer vollständigen Klasse.
Mark Hurd
3

Was Sie tun müssen, ist das Refactoring. Refactoring ist in einer solchen Situation fast unmöglich, ohne einen Unit-Test, der Ihnen das Vertrauen gibt, dass Sie nichts kaputt gemacht haben. Beginnen Sie daher mit der Erstellung von Komponententests. Dokumentieren Sie das Verhalten des Codes - aber nicht (nur) auf Papier, sondern in weiterem Code - die Unit-Tests. Sobald Sie die Tests durchgeführt haben, können Sie mit der Umstrukturierung des Codes beginnen.

user281377
quelle
11
Ich war in dieser Situation. Erstens hat VB6 erbärmliche Unit-Testsuiten. Zweitens erfordern Unit-Tests fast immer DI, und das ist in VB6 sehr schwierig, da es die objektorientierte Programmierung fürchterlich unterstützt. Ich habe noch nichts von jemandem gehört, der ein VB6-Projekt in Angriff genommen, eine Reihe von Unit-Tests geschrieben und ein Refactoring-Binge durchgeführt hat, auch wenn es sich um die Standardantwort handelt, die Sie bei einer solchen Frage auf Programmers.SE immer hören werden. Wissen Sie, wie schmerzhaft es ist, Komponententests für Logik zu schreiben, die überall in Form-Ereignishandlern eingebettet sind? Sie müssen umgestalten, bevor Sie Tests schreiben können!
Scott Whitlock
Ich würde gerne Unit-Tests zu unserem Code hinzufügen, aber ich weiß nicht, wo ich anfangen soll. Ich habe einige Unit-Tests in .net und anderen Sprachen durchgeführt, jedoch nur von Grund auf, und noch nie Tests zu einem vorhandenen Projekt hinzugefügt. Und keiner der Unit-Tests, die ich durchgeführt habe, betraf Programme, die GUIs verwenden, besonders nicht GUIs mit viel Datenbank- und Geschäftslogik, die in den Event-Handlern vermischt sind!
Dylan Nissley
1
Wenn Code nicht als testbar geschrieben wurde, müssen Sie nur Komponententests schreiben, die die einfachen und offensichtlichen Fälle abdecken und die Randfälle übersehen, die 90% der Fehler verursachen. Ich war dort, habe das getan, habe viel Zeit und Mühe verschwendet (lies Geld). Am besten stellen Sie sicher, dass der Code, den Sie ändern, leicht testbar ist - was auch immer dies in Ihrer Umgebung bedeutet, was nicht nach Komponententests klingt.
Mattnz
3

Eine Regel aus David Agans " Debugging " kommt in den Sinn: Hör auf zu denken und sieh zu. Ihnen steht zufällig eine Maschine zur Verfügung, die große Textmengen verarbeiten kann. Verwenden Sie es, um genau herauszufinden, welcher Code nicht mehr verwendet wird, und entfernen Sie ihn gnadenlos. Wenn Sie einen Fehler machen, ist dies das Ziel der Quellcodeverwaltung.

Das ist der einfache Teil. Als nächstes müssen Sie darüber nachdenken, wie Sie einen Elefanten essen. Ein Bissen nach dem anderen. Nehmen Sie das " Refactoring " von Martin Fowler auf und nehmen Sie es Funktion für Funktion, Datei für Datei. Verschrotte etwas nicht komplett und schreibe es neu, so wie du es für erforderlich hältst. Arbeiten Sie wie ein Bergsteiger und entfernen Sie niemals Ihre vorherige Sicherheit, bis die nächste vorhanden ist.

Hatten Sie schon genug Metaphern? Der Punkt ist, wenn Sie es langsam und stetig angehen und viele Verbesserungen so einfach wie das Umbenennen oder Aufteilen einer Funktion vornehmen, können Sie die fehlerhaften Teile des Codes verbessern, ohne die guten Teile zu zerstören, die durch jahrelanges Debuggen und Anfragen nach Funktionen entstanden sind . Sie möchten, dass der Code jederzeit verfügbar ist. Wenn es möglich ist, dies zu tun, während Sie auf eine modernere Sprache portieren, versuchen Sie es.

Karl Bielefeldt
quelle
Wird dies nicht ordnungsgemäß durchgeführt, gibt "In eine moderne Sprache portieren" ein "VB-Programm in C # -Syntax". Derzeit wird an einer C-portierten Java-App gearbeitet, die eigentlich "Cava" und nicht Java ist. Sie ist die schlechteste von beiden und die beste von beiden ........ Portierung richtig ist wirklich ein Umschreiben in Drag, und wie Joel es ausdrückte - das steht ganz oben auf der "Dinge, die man nicht tun sollte" -Liste.
Mattnz
Guter Punkt. Deshalb sagte ich: "Wenn es möglich ist." Wenn Sie es nicht Stück für Stück schaffen und den portierten Code auch idiomatisch schreiben können, sollten Sie es nicht versuchen.
Karl Bielefeldt
3

Ich hasse es, es zu sagen, aber ich würde mit "völlig hoffnungslos" weitermachen, als nur einen endlosen Zyklus von Patch / Enhancement zu machen und zu hoffen, dass nichts kaputt geht. Ich habe viel zu viele VB6-Projekte wie das von Ihnen beschriebene gesehen und Versuche, sie in C # /. NET umzugestalten / umzuschreiben / zu wiederholen, scheitern schrecklich, oft mit den Leuten, die für den Versuch verantwortlich sind, gefeuert zu werden.

Die Sache ist, dass früher oder später ein vollständiges Umschreiben von Grund auf notwendig sein wird. VB6- und Windows-Versionen, die dies gut unterstützen, sind rückläufig. Entwickler zu finden, die die Macken von VB6 kennen und bereit sind, an solchen Programmen zu arbeiten, wird immer seltener. Die internen Grenzen von VB6 werden bei großen Programmen wie diesem überschritten, was zu seltsamen Fehlern führt.

Wenn es einen guten Konsens und eine Verpflichtung für eine Gesamtheit gibt, beginnen Sie an diesem Punkt mit der Arbeit daran und delegieren Sie die laufende Wartung an eine andere Person (Auftragnehmer, Junior-Programmierer, was auch immer für Sie funktioniert). Wenn die Leute noch nicht überzeugt sind, warten Sie, bis die Schmerzen groß genug sind, oder gehen Sie auf grünere Weiden.

jfrankcarr
quelle
+1 Sie haben Recht, dass VB6 in modernen Windows-Versionen nicht mehr unterstützt wird. Früher oder später (wahrscheinlich früher) funktioniert Ihre Anwendung nicht mehr genau dort, wo sie benötigt wird.
Bernard
1

Einige gute Antworten möchte ich hier schon hinzufügen. Anstatt zu versuchen, alles neu zu schreiben, haben Sie vielleicht die Möglichkeit, zumindest einige dieser Module 1: 1 auf VB.NET zu portieren (natürlich müssen Sie dabei auch sehr vorsichtig sein)? Nach meiner Erfahrung kann eine solche Portierung mit ca. 5-10-mal weniger Aufwand durchgeführt werden als der Versuch, alle vorhandenen Funktionen von Grund auf neu zu erstellen. Und nachdem Sie es portiert haben, dann können Sie zu refactor beginnen - mit all den verfügbaren Tools in der .NET - Welt, wie gute Unit - Test - Tools, automatische Refactoring - Tools, real OOP usw.

Ich befand mich in einer ähnlichen Situation, in der wir ein altes 16-Bit-C ++ - Programm (150 KB LOC) in die 32-Bit-Welt migrieren mussten, in der das ursprünglich verwendete GUI-Framework nicht mehr verfügbar war. Wir haben einige Zeit gebraucht, um zu verstehen, dass das Umschreiben unrealistisch war, aber nachdem wir beschlossen hatten, dieses Ding mit C ++, C ++ / CLI und C # in die .NET-Welt zu portieren, brauchten wir nur etwa 9 Monate, um dies zu erreichen (mit etwa 1 Entwickler) Vollzeit an diesem Projekt arbeiten). Und wir hatten keine Komponententests für den GUI-Teil verfügbar, haben alle diese Teile manuell getestet.

Doc Brown
quelle
0

Steven McConnell hat ein exzellentes Buch darüber geschrieben, wie man ein solches Projekt in Angriff nimmt, obwohl es in VB6 sehr wichtig ist, es zu testen.

Schau es dir an:

Steven C. MCCONNELL: Effizientes Arbeiten mit Legacy-Code, 2. Auflage. Microsoft Press, Juni 2004.

Grundsätzlich geht es ihm darum, langsam und Stück für Stück voranzukommen. Er empfiehlt außerdem, zunächst Refactoring-Techniken zu verwenden, bei denen es sehr unwahrscheinlich ist, dass sie irgendetwas kaputtmachen, was es kurzfristig manchmal noch schlimmer macht, und fortschrittlichere Techniken zu verwenden, da der Code immer sauberer wird und Unit-Tests dies unterstützen.

QuantumOmega
quelle