it-swarm-eu.dev

Wann ist ein BIG Rewrite die Antwort?

Lesen Sie einfach die Frage zu den Big Rewrites und ich erinnerte mich an eine Frage, die ich selbst beantwortet haben wollte.

Ich habe ein schreckliches Projekt an mich weitergegeben, das in altem Java geschrieben wurde und Struts 1.0 verwendet, Tabellen mit inkonsistenten Beziehungen oder überhaupt keine Beziehungen und sogar Tabellen ohne Primärschlüssel oder Felder, die als Primärschlüssel gedacht sind, aber überhaupt nicht eindeutig sind. Irgendwie funktioniert der Großteil der App "einfach". Die meisten Seiten werden wiederverwendet (eingefügten Code kopieren) und fest codiert. Jeder, der jemals an dem Projekt gearbeitet hat, hat es in der einen oder anderen Form verflucht.

Jetzt hatte ich lange darüber nachgedacht, dem oberen Management eine vollständige Neufassung dieser schrecklichen Anwendung vorzuschlagen. Ich versuche langsam, persönliche Zeit zu sparen, aber ich habe wirklich das Gefühl, dass dies einige dedizierte Ressourcen verdient, um dies zu erreichen. Nachdem ich die Artikel über große Umschreibungen gelesen habe, habe ich Bedenken. Und das ist nicht gut, wenn ich meine Vorgesetzten davon überzeugen möchte, mein Umschreiben zu unterstützen. (Ich arbeite in einem relativ kleinen Unternehmen, sodass der Vorschlag möglicherweise genehmigt wird.)

TL; DR Wann wird die Antwort umgeschrieben und mit welchen Argumenten können Sie sie unterstützen?

288
Jonn

Entschuldigung, das wird lange dauern, aber es basiert auf persönlichen Erfahrungen als Architekt und Entwickler bei mehreren Umschreibungsprojekten.

Die folgenden Bedingungen sollten Sie veranlassen, eine Art Umschreiben in Betracht zu ziehen. Ich werde darüber sprechen, wie man entscheidet, was man danach macht.

  • Die Hochlaufzeit der Entwickler ist sehr hoch. Wenn das Hochfahren eines neuen Entwicklers länger als unten (nach Erfahrungsstufe) dauert, muss das System neu gestaltet werden. Mit Hochlaufzeit meine ich die Zeit, die der neue Entwickler benötigt, um sein erstes Commit durchzuführen (für eine kleine Funktion)
    • Frisch vom College - 1,5 Monate
    • Immer noch grün, habe aber schon vor - 1 Monat an anderen Projekten gearbeitet
    • Mittleres Niveau - 2 Wochen
    • Erfahren - 1 Woche
    • Seniorenstufe - 1 Tag
  • Die Bereitstellung kann aufgrund der Komplexität der vorhandenen Architektur nicht automatisiert werden
  • Selbst einfache Fehlerkorrekturen dauern aufgrund der Komplexität des vorhandenen Codes zu lange
  • Neue Funktionen dauern zu lange und kosten aufgrund der gegenseitigen Abhängigkeit der Codebasis zu viel (neue Funktionen können nicht isoliert werden und wirken sich daher auf vorhandene Funktionen aus).
  • Der formale Testzyklus dauert aufgrund der gegenseitigen Abhängigkeit der vorhandenen Codebasis zu lange.
  • Zu viele Anwendungsfälle werden auf zu wenigen Bildschirmen ausgeführt. Dies führt zu Schulungsproblemen für Benutzer und Entwickler.
  • Die Technologie, in der sich das aktuelle System befindet, erfordert es
    • Qualitätsentwickler mit Erfahrung in der Technologie sind zu schwer zu finden
    • Es ist veraltet (es kann nicht aktualisiert werden, um neuere Plattformen/Funktionen zu unterstützen)
    • Es gibt einfach eine viel ausdrucksstärkere übergeordnete Technologie
    • Die Kosten für die Wartung der Infrastruktur der älteren Technologie sind zu hoch

Diese Dinge sind ziemlich selbstverständlich. Wann man sich für eine vollständige Neufassung im Vergleich zu einer schrittweisen Neufassung entscheidet, ist subjektiver und daher politisch aufgeladener. Was ich mit Überzeugung sagen kann, ist, dass es falsch ist, kategorisch zu sagen, dass es nie eine gute Idee ist.

Wenn ein System schrittweise neu gestaltet werden kann und Sie die volle Unterstützung des Projektsponsorings für so etwas haben, sollten Sie dies tun. Hier ist jedoch das Problem. Viele Systeme können nicht schrittweise neu gestaltet werden. Hier sind einige der Gründe, die mir begegnet sind und die dies verhindern (sowohl technisch als auch politisch).

  • Technisch
    • Die Kopplung von Komponenten ist so hoch, dass Änderungen an einer einzelnen Komponente nicht von anderen Komponenten isoliert werden können. Eine Neugestaltung einer einzelnen Komponente führt zu einer Kaskade von Änderungen nicht nur an benachbarten Komponenten, sondern indirekt an allen Komponenten.
    • Der Technologie-Stack ist so kompliziert, dass das zukünftige Zustandsdesign mehrere Infrastrukturänderungen erfordert. Dies wäre auch bei einem vollständigen Umschreiben erforderlich. Wenn dies jedoch bei einer inkrementellen Neugestaltung erforderlich ist, verlieren Sie diesen Vorteil.
    • Das Neugestalten einer Komponente führt ohnehin zu einem vollständigen Umschreiben dieser Komponente, da das vorhandene Design so fubar ist, dass es nichts wert ist, gespeichert zu werden. Auch hier verlieren Sie den Vorteil, wenn dies der Fall ist.
  • Politisch
    • Den Sponsoren kann nicht klar gemacht werden, dass eine schrittweise Neugestaltung ein langfristiges Engagement für das Projekt erfordert. Zwangsläufig verlieren die meisten Unternehmen den Appetit auf den anhaltenden Budgetabfluss, der durch eine schrittweise Neugestaltung entsteht. Dieser Appetitverlust ist auch für ein Umschreiben unvermeidlich, aber die Sponsoren werden eher dazu neigen, fortzufahren, weil sie nicht zwischen einem teilweise vollständigen neuen System und einem teilweise veralteten alten System aufgeteilt werden möchten.
    • Die Benutzer des Systems sind zu sehr mit ihren "aktuellen Bildschirmen" verbunden. In diesem Fall verfügen Sie nicht über die Lizenz, um einen wichtigen Teil des Systems (das Front-End) zu verbessern. Durch eine Neugestaltung können Sie dieses Problem umgehen, da sie mit etwas Neuem beginnen. Sie werden immer noch darauf bestehen, "die gleichen Bildschirme" zu bekommen, aber Sie haben etwas mehr Munition zum Zurückschieben.

Beachten Sie, dass die Gesamtkosten für die schrittweise Neugestaltung immer höher sind als für eine vollständige Neufassung, aber die Auswirkungen auf die Organisation sind normalerweise geringer. Wenn Sie meiner Meinung nach ein Umschreiben rechtfertigen können und Superstar-Entwickler haben, dann tun Sie es.

Tun Sie es nur, wenn Sie sicher sein können, dass es den politischen Willen gibt, es bis zur Vollendung durchzuhalten. Dies bedeutet sowohl das Buy-In für Führungskräfte als auch für Endbenutzer. Ohne sie wirst du scheitern. Ich gehe davon aus, dass Joel deshalb sagt, dass es eine schlechte Idee ist. Executive nd Endbenutzer-Buy-In sieht für viele Architekten wie ein zweiköpfiges Einhorn aus. Sie müssen es aggressiv verkaufen und sich kontinuierlich für seine Fortsetzung einsetzen, bis es vollständig ist. Das ist schwierig, und Sie sprechen davon, Ihren Ruf auf etwas zu setzen, das manche nicht als erfolgreich ansehen wollen.

Einige Erfolgsstrategien:

  • Wenn Sie dies jedoch tun, versuchen Sie nicht, vorhandenen Code zu konvertieren. Entwerfen Sie das System von Grund auf neu. Sonst verschwendest du deine Zeit. Ich habe noch nie ein "Konvertierungs" -Projekt gesehen oder gehört, das nicht kläglich endete.
  • Migrieren Sie Benutzer nacheinander auf das neue System. Identifizieren Sie die Teams, die die meisten Probleme mit dem vorhandenen System haben, und migrieren Sie sie zuerst. Lassen Sie sie die guten Nachrichten durch Mundpropaganda verbreiten. Auf diese Weise wird Ihr neues System von innen verkauft.
  • Entwerfen Sie Ihr Framework nach Bedarf. Beginnen Sie nicht mit einem 6-monatigen Aufbau dieses Frameworks, das noch nie echten Code gesehen hat.
  • Halten Sie Ihren Technologie-Stack so klein wie möglich. Überdesign nicht. Sie können nach Bedarf Technologien hinzufügen, deren Herausnahme jedoch schwierig ist. Je mehr Ebenen Sie haben, desto mehr Arbeit müssen Entwickler leisten. Machen Sie es sich nicht von Anfang an schwer.
  • Beziehen Sie die Benutzer direkt in den Entwurfsprozess ein, aber lassen Sie sie nicht diktieren wie, um dies zu tun. Verdienen Sie ihr Vertrauen, indem Sie ihnen zeigen, dass Sie ihnen das geben können, was sie besser wollen, wenn Sie guten Designprinzipien folgen.
328
Michael Meadows

Ich habe an zwei großen Umschreibungen teilgenommen. Zuerst war ein kleines Projekt. Das zweite war das Hauptprodukt eines Softwareunternehmens.

Es gibt mehrere Fallstricke:

  • das Umschreiben dauert immer länger als erwartet.
  • umschreibungen haben keine direkten Auswirkungen/Vorteile für den Kunden.
  • kapazitäten für das Umschreiben werden nicht zur Unterstützung des Kunden verwendet.
  • beim Umschreiben verlieren Sie die Funktionalität, es sei denn, Sie verfügen über eine 100% ige Dokumentation.

Umschreibungen sind selten die eigentliche Antwort. Sie können einen Großteil des Codes umgestalten, ohne etwas zu verlieren und ohne viel Risiko.

Umschreibungen können die Antwort sein, wenn:

  • sie wechseln zu einer anderen Sprache oder Plattform.
  • sie wechseln Frameworks/externe Komponenten.
  • die vorhandene Codebasis kann nicht mehr gewartet werden.

Ich empfehle jedoch dringend den langsamen Ansatz mit Refactoring. Es ist weniger riskant und Sie halten Ihre Kunden zufrieden.

112
Toon Krijthe

Es ist Zeit für ein Umschreiben, wenn:

Die Kosten für das Umschreiben der Anwendung + die Wartung der umgeschriebenen Anwendung sind geringer als die Kosten für die Wartung des aktuellen Systems im Laufe der Zeit.

Einige Faktoren, die die Aufrechterhaltung der aktuellen Version verteuern:

  • Die Sprache ist so alt, dass man Leuten, die sie kennen, viel Geld bezahlen muss, um darin zu programmieren (COBOL).
  • (aus Erfahrung leider) Das System befindet sich auf einer Hardwarearchitektur, die so alt ist, dass sie Ebay- und COLLECT-Teile durchsuchen müssen, um sie der Maschine hinzuzufügen, auf der es ausgeführt wird, da sie nicht mehr hergestellt werden. Dies wird als "Hardware-Lebenserhaltung" bezeichnet und ist teuer, da Teile mit zunehmender Knappheit (möglicherweise) teurer werden oder (absolut) irgendwann ausgehen.
  • Es ist so komplex geworden, dass die //Here be dragons. Kommentar ist überall in Ihrem Code.
  • Sie können keine anderen Projekte schreiben und dem Unternehmen einen neuen Wert hinzufügen, weil Sie dieses hässliche Biest immer flicken.
74
Ryan Hayes

Wenn Sie eine grundlegende Änderung in der Architektur des Projekts benötigen, ist es möglicherweise Zeit, neu zu beginnen.

Trotzdem gibt es möglicherweise große Mengen an Code, die es noch wert sind, in Ihrem neuen Projekt wiederverwendet zu werden.

Beachten Sie jedoch die faire Warnung. Bei einem aktuellen Projekt wurden die Geschäftsregeln mit unzähligen Arbeitsstunden tatsächlich getestet und verfeinert. Dies gilt nicht für ein von Grund auf neu gestartetes Projekt.

Ich bezweifle, dass ein Zeitrahmen oder ein Bauchgefühl ein angemessenes Maß für solch ein drastisches Maß ist. Sie müssen klar, vertretbar und gut verstanden Gründe haben, an dieser Vorgehensweise teilzunehmen.

17
Dan McGrath

Obwohl ich Kramiis Antwort und Joels Meinung zustimme, gibt es Zeiten, in denen es angebracht ist, eine Neufassung vorzunehmen. In langlebigen Anwendungen (ich spreche von 10 bis 20 Jahren oder mehr) wird die Wartung mit der Zeit immer teurer. Dies ist darauf zurückzuführen, dass der Code immer spaghettihafter wird, da die ursprüngliche Architektur für schnelle Wartungspatches geopfert wird. Außerdem werden Entwickler für ältere Technologien seltener und teurer. Schließlich beginnt die Hardware zu altern und es wird immer schwieriger, neue Hardware, Betriebssysteme, Frameworks usw. zu finden, auf denen die alte Anwendung ausgeführt werden kann. Außerdem entwickeln sich Unternehmen weiter, und höchstwahrscheinlich wird ein älteres System die Geschäftsanforderungen des Unternehmens nicht so gut erfüllen wie ein brandneues System.

Sie müssen also alle laufenden Wartungskosten sowie die potenziellen Vorteile eines neuen Systems für das Unternehmen gegen die Kosten für das Umschreiben der Sache von Grund auf abwägen. Seien Sie sehr pessimistisch in Ihren Schätzungen über die Kosten eines Umschreibens. Es kostet fast immer mehr und dauert länger als man denkt.

12
RationalGeek

Halt! Das Umschreiben ist fast nie die Antwort. Meistens ist Refactoring eine bessere Wahl.


Natürlich gibt es Zeiten, in denen ein Umschreiben gerechtfertigt ist:

  • Sie wechseln zu einer neuen Plattform, auf der es keine Migrationstools gibt (oder die nicht billig genug geschrieben werden können).
  • Der neu zu schreibende Antrag ist trivial.
  • Der Quellcode für die ursprüngliche Anwendung geht verloren und die Wiederherstellung ist teurer als das Umschreiben.
  • Die überwiegende Mehrheit der Geschäftsregeln, die in der vorhandenen Anwendung enthalten sind, gilt nicht mehr.
  • Es gibt nur wenige aktive Benutzer des vorhandenen Codes.
  • Sie haben die Ressource (Zeit, Talent und Werkzeuge), um das Umschreiben durchzuführen.
  • Die vorhandene Anwendung kann aus rechtlichen oder praktischen Gründen nicht in einer Produktionsumgebung ausgeführt werden.

Um zu verstehen, warum ich Refactoring anstelle von Umschreiben empfehle, sollten Sie überlegen, was bei einem Umschreiben erforderlich ist. Sie müssen:

  1. Verstehen Sie die Nuancen der vorhandenen Anwendung. Dies ist normalerweise nicht trivial, wenn Sie alle subtilen Geschäftsregeln berücksichtigen, die darin enthalten sind, die Umgebung (sowohl menschlich als auch technisch), in der es betrieben wird, sowie die Vor- und Nachteile der aktuellen Lösung. Meistens befindet sich der einzige Ort, an dem diese Informationen vorhanden sind (falls vorhanden), im Quellcode der vorhandenen Anwendung. Es ist bedauerlich, dass einer der Hauptgründe für die Durchführung eines Umschreibens darin besteht, dass vorhandener Code schwer zu verstehen und zu warten ist.

  2. Reproduzieren Sie diese Funktionalität (oder eine aktualisierte Version davon) in einer neuen Anwendung, die getestet und zuverlässig ist. Bestehender Code wird von Entwicklern möglicherweise nicht verstanden, wird jedoch von den Benutzern normalerweise gut verstanden. Es entspricht möglicherweise nicht den aktuellen Geschäftsanforderungen, kann Ihnen jedoch zumindest mitteilen, was die Anwendung unter verschiedenen Umständen tut.

Große Vorteile des Refactorings sind:

  • Sie können Dinge ein kleines Stück nach dem anderen nehmen.
  • Änderungen können im Kontext der vorhandenen, funktionierenden Anwendung getestet werden.
  • Hypothesen über die Funktionsweise des vorhandenen Codes können getestet werden, indem kleine Änderungen vorgenommen und beobachtet wird, was passiert.
  • Änderungen können häufig in Phasen und nicht auf einmal an Benutzer übermittelt werden.
  • Das Lernen aus frühen Stadien des Refactorings kann spätere Stadien des Refactorings informieren.
  • Wenn Sie den Prozess teilweise abbrechen, gibt es immer noch Vorteile in Bezug auf eine sauberere Codebasis (im Gegensatz zu einem Umschreiben, zu dem abgeschlossen werden muss dem Benutzer oder den Entwicklern Vorteile bieten).

Denken Sie auch daran, dass Sie beim Umschreiben garantiert viele neue Fehler und Unordnung in die neue Codebasis einbringen.

11
Kramii

Diese Grafik könnte helfen, sie ist eine Funktion der Codebasisqualität und des Geschäftswerts der Anwendung:

enter image description here

Das Diagramm gibt vor, eine Anleitung zu sein, wann ein Re-Engineering von Legacy-Software gerechtfertigt ist und wann nicht. Wenn die Software beispielsweise einen hohen Geschäftswert hat und die Qualität des Codes schlecht ist, ist ein Re-Engineering gerechtfertigt.

10

Ich glaube, ich bin in der einzigen Situation in meiner Karriere, in der das große Umschreiben die Antwort ist:

Unternehmenszusammenschluss, enorme Überschneidung in der Systemfunktionalität. Viele, viele Systeme wurden zusammengeführt und ausgemustert, andere befinden sich noch im Prozess.

Ich habe ein System von der anderen Firma geerbt, die noch weiterlebt. Es hat eine riesige Codebasis, die früher mehrere Abteilungen unterstützte, die unseren sehr ähnlich waren, aber ein völlig anderes Design und andere Frameworks hatten. Es gibt nur noch einen Wirtschaftszweig, der genug Geld verdient, um dieses Ding in einem Zombie-Zustand am Leben zu erhalten. Das ganze alte Fachwissen ist weg, es gibt keine Dokumentation. Die Unterstützungslast ist hoch, mit wöchentlichen Ausfällen. Es wurde nicht in unsere Unternehmenssysteme integriert, da unser Unternehmen diesen bestimmten Geschäftsbereich nie unterstützt hat und wir daher nicht über die Funktionalität oder das Fachwissen verfügen.

Es sieht so aus, als ob dies der einzige Fall ist, in dem das Umschreiben erforderlich ist. Es sieht so aus, als müsste ich dieses Ungetüm herausfinden, die für dieses Geschäft bestimmten Funktionen herausholen und die Teile neu schreiben, die zu unseren vorhandenen Systemen hinzugefügt werden müssen. Sobald dies erledigt ist, können unsere bestehenden Systeme diesen neuen Sektor unterstützen, und dieses Biest kann aus seinem Elend befreit werden. Sonst werde ich meinen Verstand verlieren.

8
Jay

Ich habe für ein kleines Softwareunternehmen gearbeitet, das einige DOS-Anwendungen hatte, die für Y2K aktualisiert, als Windows 16-Bit-App neu geschrieben und dann als 32-Bit-App mit einer zusätzlichen "kleinen" Funktion (letztendlich nur von) verwendet wurden ein Kunde), der sich auf die gesamte Struktur auswirkte.

Das Verschieben des 16-Bit-Codes auf 32 hätte in einem Monat von einer Person durchgeführt werden können, aber NOOOOOOOOO, wir mussten ihn umschreiben, damit Soooooooooo viel besser ist. Dieses Ding könnte für andere Branchen angepasst werden, hätte vollständige Spezifikationen und Pseudocode, bevor sie überhaupt angefangen haben. Die Spezifikationen wurden erstellt, aber es dauerte so lange, bis nicht einmal Zeit war, den richtigen Code zu schreiben. Es wurde spät veröffentlicht, mit mehr Fehlern als das 16-Bit "angefangen" hatte (es war auf Version 3.0 und schließlich bis zu dem Punkt, an dem wir es fast eine Woche geschafft haben, ohne dass jemand einen neuen Fehler gemeldet hat).

Sie würden denken, dass das 3-4-fache Umschreiben derselben Anwendung einige Verbesserungen bringen würde, aber ich denke einfach nicht, dass ein GUI-Frontend so gerechtfertigt sein kann.

Dies war mein erster IT-Job als Leiter des technischen Supports. Ich sollte ein Buch darüber schreiben, wie man keine Software für den Vertrieb entwickelt. Natürlich haben wir viele Fehler gemacht, aber die Tatsache, dass wir weiterhin Anwendungen neu geschrieben haben, hat die Inkompetenz noch verstärkt.

7
JeffO

Ich hatte einen Fall, der Ihrem sehr ähnlich war, nur dass der Code nicht einmal Struts verwendete. Was ich stattdessen tat, waren Zielgebiete, die besonders beschissen waren UND viele Probleme verursachten. Dieser gezielte Ansatz hat uns schrittweise verbessert.

Über einen Zeitraum von 2 Jahren haben wir neben der Verbesserung auch an der Umgestaltung von Kleinigkeiten gearbeitet. Wir haben immer eine 'Härtungs'-Aufgabe in einen Projektplan eingearbeitet. Indem wir uns auf die spezifischen Bereiche konzentrierten, die nicht gut funktionierten, bekamen wir das Beste fürs Geld. Das Zeug, das funktioniert hat, haben wir alleine gelassen. Entscheidend ist auch, dass diese Arbeit im Verlauf der normalen Entwicklung durchgeführt und veröffentlicht wurde. Das Problem mit einem großen Umschreiben ist, dass Sie für ein Jahr oder länger loslegen und dann, wenn Sie zurückkommen, sich sowieso alles geändert hat und einige der bösen Fehler behoben wurden und Sie Ihren ROI verloren haben.

Wir haben das Ganze nie neu geschrieben. Wir haben diese Plattform jedoch nicht mehr für neue Arbeiten verwendet und eine neue Plattform für ein großes neues Projekt vorgeschlagen. Das wurde genehmigt und wir haben ein großartiges Produkt in angemessener Zeit geliefert.

5
Bill Leeper

Also sitze ich hier an meinem Schreibtisch und habe angefangen, den Code für dieses absolute Durcheinander einer großen Aspx-Datei, der Datenbank dahinter, neu zu schreiben und die MS Access-Schnittstelle zu MsSQL zu ersetzen.

Dieses Asp-Programm ist übersät mit Dingen wie

  • include(close.aspx), die eine Codezeile enthält, die die letzte offene Datenbankverbindung schließt.
  • Legacy-Code wurde nur zufällig auskommentiert
  • Keine Rücksicht auf Sicherheit
  • Spaghetti-Code, Tausende von Zeilen davon. Alles in einer Datei.
  • Funktionen und Variablen ohne klare Bedeutung hinter ihren Namen

Wenn wir jemals eine kleine Änderung vornehmen müssen, ist es so, als würden wir fünf Alphas-Spiele gleichzeitig im Albtraummodus spielen.

Ich wurde beauftragt, Funktionen zu replizieren und ein Produkt zu entwickeln, das anpassbar und für andere in der Branche verkaufbar ist. Das Problem ist, dass dieses Ding in den letzten 10 Jahren geschrieben wurde, um jeden einzelnen Geschäftsbedarf zu decken (nun, ich würde sowieso ungefähr fünf oder sechs Sigma davon sagen).

Wenn wir das Produkt nicht verkaufen wollten, hätten sie wahrscheinlich kein Umschreiben benötigt, da es das meiste tut, was sie wollen - vielleicht nicht elegant, aber es war nicht klug, das Geld auszugeben über Nizza Code 'das Gleiche tun.'

5
Incognito

Die vorhandene Lösung lässt sich nicht skalieren.

Ich sehe dich an, MS Access.

4
user21007

Joel Spolsky hat einen ausgezeichneten Artikel dazu: Dinge, die Sie niemals tun sollten, Teil I

Aus dem Titel geht hervor, dass er einseitig ist (er spricht darüber, warum man niemals Code werfen sollte). IMO, es steckt viel Wahrheit dahinter. Ich habe kürzlich ein Video von channel9 zum 25. Jahrestag von Excel gesehen, in dem einige Entwickler sagten, wie Selbst heute, wenn Sie in die Quelle schauen, würden Sie die Revision überprüfen und am Ende zu dem Code zurückkehren, den Excel vor 20 Jahren geschrieben hat.

Sie können nicht 100% sicher sein (wenn sogar Netscape Fehler macht (aus Joels Artikel)), [~ # ~] i [~ # ~] Sie hatten das Gefühl, dass der Artikel von Joel von Gott gesandt wurde. weil ich pessimistisch sein kann und gerne Code wegwerfe und denke, ich kann ihn immer ein zweites Mal besser schreiben, aber ich habe erst jetzt gemerkt, dass dies nur viel kostet.

Um eine konkrete Antwort zu geben, würde ich einfach sagen Sie müssen eine gründliche Kosten-Wert-Analyse durchführen Analyse.

Meine reale Welt: Eine Silverlight-App, die ich derzeit in Version 0.6 entwickle, hat eine Menge asynchroner Aufrufe, die den Code so verworren machen. Seit ich diese Woche Reactive Extensions entdeckt habe, möchte ich den größten Teil des Codes wirklich neu schreiben, aber was sage ich jetzt meinem Kunden? Das Programm funktioniert einwandfrei (mit einigen Speicherlecks), aber es ist ihnen egal? Ich kann ihnen unmöglich sagen, dass ich noch 2-3 Wochen brauche, weil ich etwas wiederholen möchte. Ich werde jedoch den Code verzweigen und neu schreiben/in meiner freien Zeit damit spielen.

Nur meine 2 Cent ok!?

4
gideon

Es gibt den klassischen Witz über "Wenn ich zu X gehen würde, würde ich nicht von hier aus anfangen".

Ich habe einmal einen Job angenommen, bei dem die Hauptmotivation des Arbeitgebers darin bestand, Talente an Bord zu bringen, um eine längst überfällige Neufassung einer geschäftskritischen App zu starten. Die Frage, die ich nicht gestellt habe, war, warum Sie überhaupt in diese Situation geraten sind. Es hätte eine rote Fahne sein sollen, ob die Ursache war

  • zu viel Druck, um Funktionen hinzuzufügen, um das Biest zu erhalten und schrittweise umzugestalten,

  • zu wenig Fähigkeit in der Abteilung,

  • zu wenig Buy-In von Kunden oder Management für inkrementelle Arbeit,

oder was auch immer, und diese Ursache schwillt an, bis das Problem ein unerträgliches Niveau erreicht hat.

Daher werde ich Joel darin zustimmen, dass ein massives Umschreiben wahrscheinlich eine sehr schlechte Idee ist - es sei denn, Sie haben feste Beweise dafür, dass alle zugrunde liegenden Gründe, warum ein umfangreiches Umschreiben so notwendig erscheint, behandelt wurden Sie werden das Problem höchstwahrscheinlich zu gegebener Zeit wiederholen.

2
Julia Hayward

Dies ist die Antwort, wenn das Unternehmen durch das Umschreiben eine Strategie verfolgen kann, die einen Wettbewerbsvorteil bietet, oder wenn es seinen Kunden auf eine Weise besser dienen kann, die die aktuelle Architektur nicht berücksichtigen kann.

Stattdessen werden Umschreibungen häufig durchgeführt, um Verwaltungssorgen zu lindern:

  • alles sollte in .NET sein,
  • unsere Entwickler sagen, unser Code ist scheiße.
  • wir fallen technisch zurück,
  • wir werden keine Ressourcen finden können, um unser System zu unterstützen, oder sehr oft.
  • es ist zehn Jahre her, also ist es Zeit.

Die meisten dieser Sorgen werden nicht eintreten, und wenn doch, könnten sie behandelt werden. Das letzte ist jedoch das Schlimmste. Es ist im Wesentlichen: Wir haben keinen Grund.

Ja, wie bei einem Auto zeigt ein System Abnutzungserscheinungen. Dies kann durch routinemäßige Wartung behoben werden. Sie wissen, was sie darüber sagen, wie ein wenig vorbeugende Wartung viel bewirkt. Als Investition ist eine routinemäßige Wartung (d. H. Umgestaltung und Standardisierung) fast immer mit geringeren Kosten verbunden als eine Umschreibung.

Wir müssen jedoch damit rechnen, dass irgendwann ein Umschreiben erforderlich sein wird. Legen Sie Termine fest und planen Sie sie vorläufig, aber wenn der Termin näher rückt, verzögern Sie die Verwirklichung anderer strategischer Ziele, bis Sie einen zwingenden Grund wie ...

In den letzten Jahren haben wir die Möglichkeit verpasst, große Kunden zu gewinnen, weil wir ihre Bedürfnisse nicht rechtzeitig oder kostspielig erfüllen konnten. Unser System wird unter Verwendung einer erweiterbaren Architektur neu geschrieben, die das Einstecken von Anpassungen ermöglicht (und nicht wie derzeit fest codiert ist). Dies wird die Zeit und die Kosten für die Unterbringung von Kunden mit besonderen Bedürfnissen drastisch reduzieren. Wir werden mehr Konten gewinnen und die Bedürfnisse unserer derzeitigen Kunden besser erfüllen.

2
Mario T. Lanza

Ich denke, der Hauptgrund, der das Umschreiben rechtfertigt, sind Plattformänderungen. Wenn Sie beispielsweise eine Windows-Desktop-GUI-Anwendung haben und der Firmeninhaber entscheidet, dass die nächste Version eine webbasierte Anwendung sein soll. Obwohl dies nicht immer der Fall ist, erfordert dies meiner Erfahrung nach meistens ein Umschreiben, es sei denn, die ursprünglichen Entwickler haben sehr modularen und wiederverwendbaren Code geschrieben (passiert kaum).

2
Craig

Laut Joel sind große Umschreibungen der schlimmste strategische Fehler , den ein Unternehmen machen kann:

Dinge, die Sie niemals tun sollten, Teil I

... Es ist wichtig, sich daran zu erinnern, dass es absolut keinen Grund gibt zu glauben, dass Sie einen besseren Job machen werden als Sie das erste Mal. Erstens haben Sie wahrscheinlich nicht einmal das gleiche Programmierteam, das an Version 1 gearbeitet hat, also haben Sie nicht wirklich "mehr Erfahrung". Sie werden nur die meisten alten Fehler noch einmal machen und einige neue Probleme einführen, die nicht in der Originalversion enthalten waren.

Das alte Mantra baue eines zum Wegwerfen ist gefährlich, wenn es auf kommerzielle Großanwendungen angewendet wird. Wenn Sie Code experimentell schreiben, möchten Sie möglicherweise die Funktion, die Sie letzte Woche geschrieben haben, zerreißen, wenn Sie an einen besseren Algorithmus denken. Das ist gut. Möglicherweise möchten Sie eine Klasse umgestalten, um die Verwendung zu vereinfachen. Das ist auch gut so. Aber das ganze Programm wegzuwerfen ist eine gefährliche Torheit, und wenn Netscape tatsächlich eine Aufsicht durch Erwachsene mit Erfahrung in der Softwareindustrie gehabt hätte, hätten sie sich möglicherweise nicht so schlecht in den Fuß geschossen.

2
user3287

Niemals, immer umgestalten - die Wahrheit ist, wenn der Code von Ihnen geschrieben wurde - werden Sie es nicht besser machen können.

Wenn Sie die Technologie nicht ändern möchten, fehlt dem Code jede Struktur (ich habe ihn vor sehr langer Zeit auf einer Website gesehen PHP Website, der Autor hat nur Spahgetti kopiert/eingefügt, anstatt include/class/function) oder Sie haben etwas von einer anderen Person übernommen, die sehr schlecht geschrieben ist.

Alles sollte als Blackbox gestaltet sein. Modulare, einfache API, was sich darin befindet ... das ist weniger wichtig :) Wenn Sie Spaghetti haben, können Sie diese möglicherweise in einer Blackbox schließen, damit kein guter Code verunreinigt wird.

2
Slawek

Bei der Umstellung auf eine völlig neue Technologie ist die gewünschte Funktionalität erforderlich.

"Völlig neu": Wenn Sie planen, neu zu schreiben, aber dieselbe Plattform verwenden, ist Refactoring und umsichtige Umstrukturierung mit ziemlicher Sicherheit die bessere Lösung. "Plattform", wie sie hier verwendet wird, ist etwas vage - betrachten Sie sie als Sprache und möglicherweise als Betriebssystem (von Linux bis Windows oder umgekehrt), aber wahrscheinlich nicht als Framework (z. B. Ersetzen von Struts durch Spring).

"Erforderlich, um die gewünschte Funktionalität bereitzustellen": Ungefähr im Jahr 2000 initiierte ich ein Projekt zum Umschreiben einer wichtigen Serverkomponente in Java aus C++, um sofort einsatzbereites Threading, einen Objektcache, zu ermöglichen). Zu dieser Zeit gab es mehrere Threading-Bibliotheken für C++, die wir hätten unterstützen müssen, und das Thread-Aktivieren eines Großteils unseres Datenbankcodes hätte ein nahezu vollständiges Umschreiben erforderlich gemacht. Bei clientgesteuerten Transaktionen. .. wird mit der alten Architektur nicht passieren.

Selbst dann bin ich mir nicht sicher, ob ich das Umschreiben durchgeführt hätte, außer dass ich detaillierte Kenntnisse über das Verhalten des aktuellen Systems hatte und es sich um relativ sauberen Code handelte, der in den elf Lebensjahren nicht sehr viele Warzen entwickelt hatte.

1
Anon

Nun, ich kann mir hypothetische Szenarien vorstellen, in denen ich die vorhandene Codebasis einfach wegwerfen könnte (hypothetische Situationen, in denen die Bucky Balls kein Gewicht und kein Volumen haben und in denen es niemanden interessiert, ob wir Wochen oder Monate an Produktivität verlieren, wenn wir versuchen, übersehene Funktionen und Fehler hinzuzufügen Fixes im System, und wo das System von einer Organisation so trivial und gehasst ist, dass ich das gesamte Ding und die Armee von Servern in zehn Minuten durch Notepad ++ und ein Netbook ersetzen und die Produktivität und Moral aller auf ganzer Linie steigern kann.)

Für fast jedes reale Szenario würde ich jedoch nur empfehlen, das Refactoring durchzuführen. ^ _ ^. Es gibt in der Regel zu viele versteckte, unerwartete Kosten für das Umschreiben, wenn undokumentierte gesetzliche und geschäftliche Anforderungen auftauchen und in letzter Minute das Zusammenhacken von Dingen in letzter Minute beginnt.

== Refactoring an Ort und Stelle zum Wohle der Allgemeinheit und so weiter ==

Refactoring von Legacy-Code mit dem regulären alten inkrementellen Ansatz,

  1. Wenn Sie die Möglichkeit haben, in UML zu konvertieren und zu dokumentieren, welche kleine knorrige Architektur es gibt.
  2. Wenn Sie sich in der Versionskontrolle befinden, sollten Sie einige Code-Abwanderungsberichte erstellen und herausfinden, welche Dateien und Dateibereiche am häufigsten geändert wurden. Notieren Sie sich diese, da dies wahrscheinlich die Bereiche sind, mit denen Sie sich zuerst befassen möchten.
  3. Bevor Sie Code ändern, versuchen Sie immer, eine gewisse Testabdeckung hinzuzufügen (selbst hässliche Full-Stack-Funktionstests reichen aus). Wenn Sie sich mit einer großen, chaotischen Logik zum Extrahieren von prozeduralem Code befassen, beabsichtigen Sie, in eine Methode oder Funktion mit vernünftigem Namen zu wechseln und wenn möglich einige Testfälle hinzuzufügen, die Ihre neue Methode verifizieren. Machen Sie jeden gottesfürchtigen Hack, den Sie machen müssen, und parametrisieren Sie die Änderung, wenn möglich, wenn es sich um etwas handelt, das häufig wie Randbreite oder Titel optimiert wird, damit es beim nächsten Mal etwas einfacher zu aktualisieren ist.
  4. Verwenden Sie das Adaptermuster und arbeiten Sie daran, die knorrigen Teile des Legacy-Codes unter einem Teppich aus logisch benannten Klassen und Methoden zu verstecken, damit Sie sich für die häufigsten Aufgaben, die Sie und die anderen Entwickler ausführen, keine Gedanken über die beängstigenden Teile machen müssen, die dahinter stecken Ihr Rücken hinter diesen netten kleinen sauberen Methoden und Klassen, hinter denen Sie diesen alten Code versteckt haben - wie jene netten Familien, die deformierte mörderische ehemalige Zombie-Familienmitglieder in Scheunen halten, damit sie nicht den Alltag der Menschen verderben Bauernhof. . . normalerweise.
  5. Während Sie weiter wegschnitzen und die Abschnitte des Codes bereinigen, verbessern Sie weiterhin Ihre Testabdeckung. Jetzt können Sie noch tiefer graben und bei Bedarf noch mehr Code mit immer größerem Vertrauen "umschreiben".
  6. Wiederholen oder wenden Sie zusätzliche Refactoring-Ansätze an, um Ihre Codebasis weiter zu verbessern.

Verzweigung durch Abstraktion

  1. Definieren Sie die Problemstelle in dem Code, den Sie entfernen möchten (die Persistenzschicht, den PDF-Generator, den Rechnungszählmechanismus, den Widget-Generator usw.).
  2. führen Sie einige Funktionstestfälle (automatisiert oder manuell, aber Sie wissen, dass sie automatisiert sind) für die Codebasis aus, die diese Funktionalität zusammen mit dem allgemeinen Verhalten zum Ziel hat.
  3. Extrahieren Sie die mit dieser Komponente verbundene Logik aus der vorhandenen Quellbasis in eine Klasse mit einer angemessenen Schnittstelle.
  4. Überprüfen Sie, ob der gesamte Code jetzt die neue Schnittstelle verwendet, um die Aktivität X auszuführen, die zuvor zufällig im Code verteilt wurde (Grep die Codebasis, füge der neuen Klasse eine Ablaufverfolgung hinzu und überprüfe, ob Seiten aufgerufen werden sollen usw.) Sie können steuern, welche Implementierung verwendet wird, indem Sie eine einzelne Datei ändern. (Objektregistrierung, Factory-Klasse, unabhängig von IActivityXClass = Settings.AcitivtyXImplementer ();)
  5. führen Sie Funktionstestfälle erneut aus, in denen überprüft wird, ob mit Activity X in Ihrer neuen Klasse noch alles funktioniert.
  6. Schreiben Sie nach Möglichkeit Komponententests um die neue Wrapper-Klasse für Aktivität X.
  7. implementieren Sie eine neue Klasse mit weniger verrückter Spaghetti-Logik als die Legacy-Implementierung, die an derselben Schnittstelle wie die Legacy-Klasse arbeitet.
  8. stellen Sie sicher, dass die neue Klasse die Komponententests besteht, die Sie für die Legacy-Klasse geschrieben haben.
  9. aktualisieren Sie Ihren Code, indem Sie die Registrierung/Factory-Methode/was auch immer ändern, um die neue Klasse anstelle der alten Klasse zu verwenden.
  10. stellen Sie sicher, dass Ihre Funktionstests noch bestanden sind.

Offenes geschlossenes Prinzip und eine gemeinsame Geschäftslogik/Persistenzschicht

Bis zu einem gewissen Grad können Sie möglicherweise Ihre Präsentations-, Geschäfts- und Persistenzschicht trennen und eine neue App schreiben, die vollständig abwärtskompatibel mit der Legacy-Lösung ist oder zumindest weiterhin Daten verarbeiten kann, die von der Legacy-Lösung eingegeben wurden. Ich würde diesen Ansatz wahrscheinlich nicht empfehlen, aber manchmal ist es ein vernünftiger Kompromiss zwischen Zeit/Zeitplan/Ressourcen/erforderlichen neuen Funktionen.

  • Trennen Sie mindestens die Präsentationsschicht von der Geschäfts- und der Persistenzschicht.
  • implementieren Sie eine neue Benutzeroberfläche und eine bessere Präsentationsschicht, die dieselbe gemeinsame Geschäfts- und Persistenzschicht verwendet.
  • Stellen Sie sicher, dass mit einer neuen Benutzeroberfläche erstellte Daten die alte Benutzeroberfläche nicht beschädigen. (Sie werden in heißem Wasser sein, wenn Benutzer des neuen Tools Benutzer des alten Tools unterbrechen). Wenn Sie eine vollständige Abwärtskompatibilität anstreben, sollten Sie alles auf denselben Persistenzschichten speichern. Wenn Sie nur die Vorwärtskompatibilität mit dem neuen Tool wünschen, verwenden Sie eine neue Datenbank und neue Tabellen oder Erweiterungstabellen, um Daten zu verfolgen, die sich nicht im Altsystem befinden.
  • Für neue Funktionen und Anforderungen an die Persistenzschicht müssen neue Tabellen und Methoden hinzugefügt werden, um die vorhandene Legacy-Logik nicht zu ändern oder Spalten und Einschränkungen für vorhandene Tabellen hinzuzufügen. z.B. Wenn Sie mit der Verfolgung des Notfallkontakts des Arbeitgebers beginnen müssen und einige andere Felder die vorhandene Mitarbeitertabelle nicht ändern (wir haben keine Ahnung, welche Annahmen die alten Daten zu dieser Tabelle machen), fügen Sie eine Erweiterungstabelle employee_ext id, employee_id, Emergency_contact_id, etc_id hinzu.
  • Migrieren Sie Benutzer langsam auf ein neues System. Wenn möglich, versetzen Sie das Legacy-System in den schreibgeschützten Modus oder fügen Sie eine Warnung hinzu, die den Benutzern mitteilt, dass es nach dem Datum X nicht mehr verfügbar ist.
  • implementieren Sie alle fehlenden Funktionen oder Geschäftsanforderungen mit hoher Priorität in der neuen Benutzeroberfläche
  • rollover-Benutzerbasis.
  • fahren Sie fort, um die Benutzer der Geschäftslogik und der Persistenzschicht mit anderen Refactoring-Methoden zu bereinigen.
0
Keith Brings

Ich würde sagen, es gibt eine dritte Kategorie im Bereich Refactor vs Rewrite ... Und das aktualisiert Ihre Sprachversionen, Compiler und Bibliotheken ... Manchmal hat die bloße Übernahme moderner Codierungstechniken einen großen Vorteil.

Nehmen wir zum Beispiel C #, v7-Code schreibt viel sauberer, sicherer und prägnanter als v2. Dinge wie der Elvis- und der Null-Koaleszenz-Operator helfen eine Menge.

Das Wechseln von Compilern kann auch älteren Codes neues Leben einhauchen. Vielleicht auch neue Bibliotheken, die das Arbeiten und Implementieren erleichtern ... Das Netzwerk ist ein hervorragendes Beispiel für ein Spektrum von Implementierungsschwierigkeiten.

Auch eingebettete Linux-Systeme ... Denken Sie über die Installation neuer Tools nach - wechseln Sie von svn zu git. oder fügen Sie Vi zu Ihrem System hinzu usw. usw.

Es muss nicht immer ein Refactor oder ein Rewrite sein. Ihre Architektur muss wahrscheinlich verbessert werden, aber es funktioniert. Vielleicht müssen Sie nur darüber nachdenken, wie Ihr Code geschrieben ist usw.

0
visc

Um zu entscheiden, an welchem ​​Punkt Sie von vorne beginnen sollen, müssen Sie herausfinden, wo der Wert der Fortsetzung Ihres aktuellen Projekts hinter dem Wert für den Neuanfang zurückbleibt.

Der Grund dafür ist, dass Sie die Entwicklungsgeschwindigkeit des Teams für das neue Projekt genau abschätzen, bis Sie es tatsächlich starten. Wenn Sie jedoch anhand einer SEHR konservativen Schätzung Ihrer Entwicklungsgeschwindigkeit für das neue Projekt eine lohnende Kapitalrendite erzielen, haben Sie ein Geschäftsmodell für einen Neuanfang.

0
Nobody

Bei meiner Metrik müssen Sie zwei Bedingungen erfüllen, um ein Umschreiben zu rechtfertigen:

  1. Nach dem Umschreiben sind neue Funktionen einfacher/schneller/weniger fehlerhaft zu schreiben
  2. Das Umschreiben dauert weniger oder genauso lange wie das Hinzufügen der aktuellen neuen Funktion.

Selbst dann möchten Sie den Umfang Ihres Umschreibens einschränken. Zum Beispiel hatten wir eine Legacy-Software in einem Unternehmen, das in C++ mit der Denkweise eines C-Programmierers geschrieben wurde, der nichts über Modularität wusste. Das Endergebnis war Speghetti-Code in Form einer Finite-State-Maschine, die mehrere Klassen und DLLs umfasste. Wir hatten eine neue Anforderung, die sich stark von den im Code enthaltenen Annahmen unterschied und Teil des patentierten Mehrwerts des Unternehmens für seine Kunden sein sollte.

Nachdem ich Zeit mit dem Code verbracht hatte, der andere Funktionen implementiert, hatte ich eine wirklich gute Vorstellung davon, wie lange es dauern würde, um herauszufinden, welche der verschiedenen switch-Anweisungen ich ändern müsste usw. Mein Vorschlag war, den Codeabschnitt neu zu schreiben Die riesige Finite-State-Maschine - ich sollte weniger Zeit brauchen, als den vorhandenen Code zu erweitern. Ich konnte mich zu einer konsolidieren DLL, was früher drei war, und eine viel objektorientiertere Struktur bereitstellen, die es viel einfacher machen würde, die kritischen neuen Funktionen zu erledigen und es auch einfacher zu machen neue Funktionalität hinzufügen.

Es gab drei andere Anwendungen, die die Bibliotheken verwendeten, die neu geschrieben werden mussten, sodass ich diese Programme nicht vollständig neu schreiben musste. Der Umfang war auf die Bibliothek beschränkt und darauf, was erforderlich war, um die Bibliothek an die vorhandene Software zu binden. Meine Schätzungen waren bei weitem nicht falsch, und die Arbeit hat sich bezahlt gemacht. Kurz nach der Neugestaltung wurde ich beauftragt, eine neue Funktion hinzuzufügen. Was mich mit der alten Struktur eine Woche gekostet hätte, hat mich mit der neuen Struktur nur einen Tag gekostet.

0
Berin Loritsch

Das OP gibt nicht den Umfang des Projekts an, aber der wichtigste Hinweis, den ich nahm, war "in alten [Sprache/Dialekt] mit alten [Bibliotheken] geschrieben", was für mich die Haupttreiber eines Umschreibens sind. Tatsächlich erkennen die meisten Projekte, an denen ich mit einer signifikanten Marktlebensdauer teilgenommen habe, dass die Anpassung von Updates an Compiler/Interpreter/Betriebssysteme eine wichtige Aufgabe bei der Aufrechterhaltung der Codebasis ist.

Kurz gesagt, ich würde das Umschreiben in Phasen planen und zuerst das Update in libs priorisieren. Es kann sein, dass Sie unterwegs andere Optimierungen vornehmen können, aber die Tatsache, dass Sie einige Änderungen auf eine spätere Phase verschieben möchten, kann eine gute Möglichkeit sein, den Zeitplan einzuhalten und nicht "hängen zu bleiben".

0
MarkHu