Ich hatte meinen Anteil an Projekten, bei denen das erste, was ich denke, ist: "Dieser Code ist scheiße; lass ihn einfach in framework X umschreiben." Jeder fühlt den Drang irgendwann. In der Tat, ich denke, ich hatte das Bedürfnis, so ziemlich jedes Projekt neu zu schreiben, an dem ich je teilgenommen habe.
Es ist jedoch anerkannte Weisheit, dass eine vollständige Neuschreibung im Allgemeinen eine schlechte Idee ist. Die Frage ist: Wann betrachtest du ein Projekt und sagst: "OK, es ist Zeit, von vorne zu beginnen."
Welche Art von Metriken oder Beispielen können Sie angeben, wo ein Rewrite wirklich notwendig war? Wie schlimm muss der Code sein? Wie alt kann ein Projekt vor dort zu viel investiert werden?
Schreiben Sie niemals Software neu. Refactor es während seiner gesamten Lebensdauer.
Ich hatte meinen Anteil an Projekten, bei denen das erste, was ich denke, ist: "Dieser Code ist scheiße; lass ihn einfach in framework X umschreiben." Jeder fühlt den Drang irgendwann. In der Tat, ich denke, ich hatte das Bedürfnis, so ziemlich jedes Projekt neu zu schreiben, an dem ich je teilgenommen habe.
Es ist jedoch anerkannte Weisheit, dass eine vollständige Neuschreibung im Allgemeinen eine schlechte Idee ist. Die Frage ist: Wann betrachtest du ein Projekt und sagst: "OK, es ist Zeit, von vorne zu beginnen."
Welche Art von Metriken oder Beispielen können Sie angeben, wo ein Rewrite wirklich notwendig war? Wie schlimm muss der Code sein? Wie alt kann ein Projekt vor dort zu viel investiert werden?
In der Regel zeigt dieser Punkt die Kosten / Nutzen-Analyse an, dass ein Total-Neuschreiben mehr Geld spart als das alte System.
Verschiedene Faktoren können diese Analyse jedoch beeinflussen (wie Plattformen, die nicht mehr unterstützt werden, talentierte Entwickler werden schwer zu finden, etc.).
Wenn Sie die Kosten / Nutzen-Analyse auf die richtige Art und Weise durchführen, werden Sie sehen, dass es sich nie lohnt, ein vollständiges Neuschreiben durchzuführen. Das kostet nur Zeit und Kopfschmerzen.
Wenn es so schlimm ist, dass es neu geschrieben werden muss .... nennen Sie es Ersatz . Fügen Sie einige neue Funktionen hinzu, erleichtern Sie die Pflege und Verwendung. Entwickeln Sie es mit der neuesten Technologie für Ihr Unternehmen.
Die höheren Ups glauben, dass es mehr Wert ist, etwas zu ersetzen, das kaum mit etwas Neuem zu tun hat. verbessert, wenn es den Arbeitsablauf verbessern wird & amp; Produktivität.
Stellen Sie sicher, dass Sie es nicht als Neufassung von Mist-Code bezeichnen, weil die Leute, die es geschrieben haben, immer noch da sind.
Vielleicht möchten Sie sich Iterative Entwicklung ansehen. Am Anfang zucken ich und wahrscheinlich fast jeder "Senior" Entwickler, wenn wir darüber lesen. Keine Vorausplanung? Kein Denken in Abstracts und Allgemeinheiten? Mach es einfach fertig? Produziert das nicht schlechten Code? Nicht wirklich. Es wird genau das produzieren, was du brauchst, und wenn du zurückkommst und eine Funktion ansiehst, die entworfen wurde, um eine Sache zu tun, refaktorierst du sie, um mehr zu tun, und so weiter.
Dies ist effektiv ein konstantes Neuschreiben, aber nicht immer. Jene Funktionen, die nie refaktoriert werden, wurden extrem schnell erledigt und tun genau das, was sie tun sollen. Sie haben es auch geschafft, es in einem Bruchteil der Zeit zu implementieren, weil Sie nicht 10 Schritte vorausgedacht und es generisch gemacht haben.
Sie können anfangen, es hier zu lesen: Ссылка
Um Ihre Frage direkt zu beantworten, halten Sie sich an den Grundsatz "Wenn es nicht kaputt ist, reparieren Sie es nicht". Es sei denn, es gibt einen Bedarf jenseits von "Gott, der hässlich ist, ich möchte das aufräumen", schreibe nicht um, was du getan hast.
Wenn der Code absolut Null der Anforderungen für das Projekt erfüllt, könnte es ein guter Zeitpunkt sein, es neu zu schreiben.
Ein "rewrite" (oder zumindest ein ernsthaftes Refactoring) ist manchmal der beste Weg vorwärts, wenn Sie feststellen, dass eine Lösung nicht skalierbar ist.
Ein Beispiel dafür ist ein Malbuch, das ich in den 80er Jahren geschrieben habe. Es begann mit ein bisschen Spaß an einer 16-Farben-Bitmap zu arbeiten. Als es 20kB BASIC-Code war, dachte ich "Ich sollte das umschreiben, damit es 16 oder 256 Farbbilder verarbeiten kann". Aber es war "zu viel Arbeit". Als es 50kB war, war klar, dass es wirklich neu geschrieben werden musste, aber es würde einfach zu lange dauern. Also fuhr ich fort, Code hinzuzufügen, der darauf basierte, dass es ein 16-farbiges Bild war, bis es den Punkt erreichte, wo es 140kB war und absolut unpraktisch war, es neu zu schreiben. Ich bedauerte es immer, die Kugel nicht zu beißen, wenn die Überarbeitung nur ein paar Stunden Arbeit war.
Ein anderes Beispiel: Ich habe an einem Vektor-Kunst-Paket gearbeitet, das Ereignisse um alle Objekte in seiner Szenengraph-Hierarchie sendet. In der Anfangsphase hatte es ein paar Dutzend Objekte und, wie mein Manager es ausdrückte, "wir können mehr als 10.000 Objekte pro Sekunde senden", so dass die Übertragungen fortgesetzt wurden. Ich schlug vor, interessierte Objekte dazu zu bringen, die Ereignisse zu abonnieren, die sie brauchten, um Ineffizienz zu beseitigen, aber es gab "keine Notwendigkeit". 2 Jahre (40 Mann Jahre Anstrengung) später wurde das Programm für 2-4 Sekunden angehalten, weil der Szenengraph mehr wie 500 Objekte enthielt und die 2 Broadcast-Ereignisse auf 40 oder so angestiegen waren.
Dieses Muster wurde in mehreren Projekten wiederholt, an denen ich im Laufe der Jahre beteiligt war - du erkennst einen ernsthaften Konstruktionsfehler oder technische Schulden und zögerst es, es zu reparieren, weil (a) es noch kein Problem ist und ( b) es würde zu viel Zeit kosten, es jetzt zu klären. Im Laufe der Zeit wird es linear eher ein Problem, aber exponentiell teurer zu beheben. Obwohl es mehr und mehr korrigiert werden muss, ist es schwieriger, die Kosten für die Korrektur zu rechtfertigen.
In diesen Fällen muss der technische Schulden- oder Designfehler so früh wie möglich gelöst werden. Es braucht Mut (wenn Sie ein Manager sind) oder Überzeugungskraft (wenn Sie ein Untergebener sind), um Ihren Zeitplan für eine Woche zurückzuhalten, aber stellen Sie sich vor, keinen Rückgriff zu haben, sondern 2 Monate dem Fix in Jahren zu widmen! p>
Dieses Argument gilt natürlich nicht für alle Fälle. Sie müssen das Kosten-Nutzen-Verhältnis eines vorgeschlagenen Fixes bewerten und die Skalierbarkeit des Problems berücksichtigen. Wenn das Problem eine Konstante ist, können Sie es jederzeit für die gleichen Kosten zu einem späteren Zeitpunkt beheben. Wenn jede neue Klasse, die du zu deinem System hinzufügst, den Fehler verschärft, und du erwartest, Hunderte neuer Klassen hinzuzufügen, dann gehe zurück und repariere es jetzt.
Eine der wenigen Situationen, in denen ein Neuschreiben erforderlich sein kann, ist, wenn die Sprache veraltet ist und keine Entwickler mehr zur Verfügung stehen. In diesem Fall müssen Sie möglicherweise sogar guten Code, der perfekt funktioniert, neu schreiben.
Und fügen Sie der Verletzung eine Beleidigung hinzu, können Sie leicht mit etwas Schlimmerem enden, als Sie begonnen haben.
Einer der großen propagandistischen Aspekte der Programmierung ist, dass sie für die Wiederverwendung von Code und / oder Modulen entworfen werden sollte. Mit anderen Worten, Funktionalität sollte in diskrete wiederverwendbare Teile aufgeteilt werden. Wenn Sie Code haben, der tatsächlich etwas tut und eine Anforderung erfüllt, besteht das Argument nicht darin, dass der Code neu geschrieben werden muss, sondern vielmehr in einen Zustand, in dem er wiederverwendet werden kann / p>
Das bedeutet nicht, dass Sie keine großen Code-Teile wegwerfen und ersetzen sollten. Tatsächlich sagt uns die Idee des Refactorings, genau das zu tun. Die Idee ist jedoch auch, dass wir währenddessen Tests durchführen und verbessern sollten, um ein kompatibles Verhalten und eine erhöhte Wiederverwendbarkeit und Modularisierung sicherzustellen.
Wenn Sie sogar ein Modul verwenden können, das eine Anforderung erfüllt, und es in Version 2 erneut verwenden können, haben Sie die Codebasis definitionsgemäß nicht verworfen und neu gestartet . Und warum solltest du, wenn auch in schlechtem Code, normalerweise nur ein paar Optimierungen benötigen, um es in guten Code aufzuräumen? Ganz zu schweigen von den Perlen des guten oder sogar "guten" Codes, die im Projekt existieren.
Disclaimer: Ich arbeite an einer Universität, wo der Zweck von Software darin besteht, die Gültigkeit neuer Ideen zu begründen oder zu widerlegen. Während einige Akademiker seit über 20 Jahren dieselbe Software verwenden (Beispiele: der Glasgow Haskell Compiler und die ACL2 Theorembeweiser , viele Akademiker verlassen alte Projekte und starten regelmäßig neue Projekte.Für viele von uns ist die richtige Faustregel Solange die Software produktiv bleibt, sollten Sie das Refactoring verbessern und nicht von vorn beginnen. "Produktiv" bedeutet verschiedene Dinge in verschiedenen Kontexten, aber einige Beispiele sind:
Für uns kann eine vollständige Neufassung gerechtfertigt sein, wenn sie die Möglichkeit bietet, neue Ideen auszuprobieren . Ein riskanterer Schritt für eine vollständige Neufassung ist es, eine größere Wirkung zu erzielen. Zum Beispiel sind wir dabei, einen Optimierer in Haskell neu zu schreiben (er wurde in Objective Caml geschrieben), weil wir durch das Schreiben in Haskell mehr Leute dazu bringen können, ihn zu benutzen, und wir können seine Glaubwürdigkeit durch die Verwendung in einem großen System etablieren Open-Source-Aufwand. Aber es ist immer noch ein riskantes Unterfangen für uns, weil es schwierig ist, Papiere über alte Ideen zu veröffentlichen, die in neuen Implementierungen neu geschrieben wurden.
Die kurze Version ist das eine vollständige Neufassung ist fast nie gerechtfertigt .
Der Grund, warum Sie es neu schreiben wollen, ist, weil die Probleme, die Sie jetzt sehen, nicht vorhergesehen wurden, als es geschrieben wurde, es könnte zwei Gründe dafür geben 1. Es war nicht beabsichtigt zu tun, was es gerade macht oder 2. Es war einfach ein Fehler.
Geben Sie ein sehr gründliches Denken, wenn Sie in der Lage sind, all die Dinge vorauszusehen, die es erfordern könnte.
Nur dann überschreiben Sie es. Aber im Allgemeinen wird der am besten geschriebene und gut verwaltete Code nur refactoring benötigt.
Prost, Pavan
Wenn es bereits in einer modernen Sprache ist, refactor statt neu schreiben.
Wenn ich eine Cobol-App hätte und mein Mainframe irgendwann weg wäre, wäre es an der Zeit, es neu zu schreiben. Wenn ich eine alte App in FoxPro gefunden habe und wir noch die Funktionalität benötigen, schreiben Sie sie neu.
Aber wenn es in Java ist, egal wie schlecht es ist, refaktorieren Sie ein Bit nach dem anderen. Es wird ehrlich weniger weh tun.
Schreibt nur, wenn eines von zwei Dingen wahr ist:
Das bestehende Programm funktioniert sowieso nicht und funktioniert nicht annähernd. (Mit anderen Worten, Sie haben eine "90% ige" Codebasis von Ihren Vorgängern geerbt, kein tatsächliches Produkt.)
Ein schrittweises Re-Factoring ist unmöglich, weil das neue Programm eine grundlegend andere Architektur benötigt und auf einem anderen Technologie-Stack oder was auch immer laufen muss.
Mit anderen Worten, die Richtlinie (es gibt Ausnahmen, aber sie sind selten; Sie werden wahrscheinlich nicht schlecht falsch nach dieser Richtlinie gehen) ist, nur umschreiben, wenn Schritt-für-Schritt-Re-Factoring von einem funktionierenden Produkt nicht ist eine Option.
Schreiben Sie niemals Software neu. Refactor es während seiner gesamten Lebensdauer.
Schreibt nur, wenn eines von zwei Dingen wahr ist:
Das bestehende Programm funktioniert sowieso nicht und funktioniert nicht annähernd. (Mit anderen Worten, Sie haben eine "90% ige" Codebasis von Ihren Vorgängern geerbt, kein tatsächliches Produkt.)
Ein schrittweises Re-Factoring ist unmöglich, weil das neue Programm eine grundlegend andere Architektur benötigt und auf einem anderen Technologie-Stack oder was auch immer laufen muss.
Mit anderen Worten, die Richtlinie (es gibt Ausnahmen, aber sie sind selten; Sie werden wahrscheinlich nicht schlecht falsch nach dieser Richtlinie gehen) ist, nur umschreiben, wenn Schritt-für-Schritt-Re-Factoring von einem funktionierenden Produkt nicht ist eine Option.
In der Regel zeigt dieser Punkt die Kosten / Nutzen-Analyse an, dass ein Total-Neuschreiben mehr Geld spart als das alte System.
Verschiedene Faktoren können diese Analyse jedoch beeinflussen (wie Plattformen, die nicht mehr unterstützt werden, talentierte Entwickler werden schwer zu finden, etc.).
Wenn Sie die Kosten / Nutzen-Analyse auf die richtige Art und Weise durchführen, werden Sie sehen, dass es sich nie lohnt, ein vollständiges Neuschreiben durchzuführen. Das kostet nur Zeit und Kopfschmerzen.
Vielleicht möchten Sie sich Iterative Entwicklung ansehen. Am Anfang zucken ich und wahrscheinlich fast jeder "Senior" Entwickler, wenn wir darüber lesen. Keine Vorausplanung? Kein Denken in Abstracts und Allgemeinheiten? Mach es einfach fertig? Produziert das nicht schlechten Code? Nicht wirklich. Es wird genau das produzieren, was du brauchst, und wenn du zurückkommst und eine Funktion ansiehst, die entworfen wurde, um eine Sache zu tun, refaktorierst du sie, um mehr zu tun, und so weiter.
Dies ist effektiv ein konstantes Neuschreiben, aber nicht immer. Jene Funktionen, die nie refaktoriert werden, wurden extrem schnell erledigt und tun genau das, was sie tun sollen. Sie haben es auch geschafft, es in einem Bruchteil der Zeit zu implementieren, weil Sie nicht 10 Schritte vorausgedacht und es generisch gemacht haben.
Sie können anfangen, es hier zu lesen: Ссылка
Um Ihre Frage direkt zu beantworten, halten Sie sich an den Grundsatz "Wenn es nicht kaputt ist, reparieren Sie es nicht". Es sei denn, es gibt einen Bedarf jenseits von "Gott, der hässlich ist, ich möchte das aufräumen", schreibe nicht um, was du getan hast.
Wenn es so schlimm ist, dass es neu geschrieben werden muss .... nennen Sie es Ersatz . Fügen Sie einige neue Funktionen hinzu, erleichtern Sie die Pflege und Verwendung. Entwickeln Sie es mit der neuesten Technologie für Ihr Unternehmen.
Die höheren Ups glauben, dass es mehr Wert ist, etwas zu ersetzen, das kaum mit etwas Neuem zu tun hat. verbessert, wenn es den Arbeitsablauf verbessern wird & amp; Produktivität.
Stellen Sie sicher, dass Sie es nicht als Neufassung von Mist-Code bezeichnen, weil die Leute, die es geschrieben haben, immer noch da sind.
Eine der wenigen Situationen, in denen ein Neuschreiben erforderlich sein kann, ist, wenn die Sprache veraltet ist und keine Entwickler mehr zur Verfügung stehen. In diesem Fall müssen Sie möglicherweise sogar guten Code, der perfekt funktioniert, neu schreiben.
Und fügen Sie der Verletzung eine Beleidigung hinzu, können Sie leicht mit etwas Schlimmerem enden, als Sie begonnen haben.
Ein "rewrite" (oder zumindest ein ernsthaftes Refactoring) ist manchmal der beste Weg vorwärts, wenn Sie feststellen, dass eine Lösung nicht skalierbar ist.
Ein Beispiel dafür ist ein Malbuch, das ich in den 80er Jahren geschrieben habe. Es begann mit ein bisschen Spaß an einer 16-Farben-Bitmap zu arbeiten. Als es 20kB BASIC-Code war, dachte ich "Ich sollte das umschreiben, damit es 16 oder 256 Farbbilder verarbeiten kann". Aber es war "zu viel Arbeit". Als es 50kB war, war klar, dass es wirklich neu geschrieben werden musste, aber es würde einfach zu lange dauern. Also fuhr ich fort, Code hinzuzufügen, der darauf basierte, dass es ein 16-farbiges Bild war, bis es den Punkt erreichte, wo es 140kB war und absolut unpraktisch war, es neu zu schreiben. Ich bedauerte es immer, die Kugel nicht zu beißen, wenn die Überarbeitung nur ein paar Stunden Arbeit war.
Ein anderes Beispiel: Ich habe an einem Vektor-Kunst-Paket gearbeitet, das Ereignisse um alle Objekte in seiner Szenengraph-Hierarchie sendet. In der Anfangsphase hatte es ein paar Dutzend Objekte und, wie mein Manager es ausdrückte, "wir können mehr als 10.000 Objekte pro Sekunde senden", so dass die Übertragungen fortgesetzt wurden. Ich schlug vor, interessierte Objekte dazu zu bringen, die Ereignisse zu abonnieren, die sie brauchten, um Ineffizienz zu beseitigen, aber es gab "keine Notwendigkeit". 2 Jahre (40 Mann Jahre Anstrengung) später wurde das Programm für 2-4 Sekunden angehalten, weil der Szenengraph mehr wie 500 Objekte enthielt und die 2 Broadcast-Ereignisse auf 40 oder so angestiegen waren.
Dieses Muster wurde in mehreren Projekten wiederholt, an denen ich im Laufe der Jahre beteiligt war - du erkennst einen ernsthaften Konstruktionsfehler oder technische Schulden und zögerst es, es zu reparieren, weil (a) es noch kein Problem ist und ( b) es würde zu viel Zeit kosten, es jetzt zu klären. Im Laufe der Zeit wird es linear eher ein Problem, aber exponentiell teurer zu beheben. Obwohl es mehr und mehr korrigiert werden muss, ist es schwieriger, die Kosten für die Korrektur zu rechtfertigen.
In diesen Fällen muss der technische Schulden- oder Designfehler so früh wie möglich gelöst werden. Es braucht Mut (wenn Sie ein Manager sind) oder Überzeugungskraft (wenn Sie ein Untergebener sind), um Ihren Zeitplan für eine Woche zurückzuhalten, aber stellen Sie sich vor, keinen Rückgriff zu haben, sondern 2 Monate dem Fix in Jahren zu widmen! p>
Dieses Argument gilt natürlich nicht für alle Fälle. Sie müssen das Kosten-Nutzen-Verhältnis eines vorgeschlagenen Fixes bewerten und die Skalierbarkeit des Problems berücksichtigen. Wenn das Problem eine Konstante ist, können Sie es jederzeit für die gleichen Kosten zu einem späteren Zeitpunkt beheben. Wenn jede neue Klasse, die du zu deinem System hinzufügst, den Fehler verschärft, und du erwartest, Hunderte neuer Klassen hinzuzufügen, dann gehe zurück und repariere es jetzt.
Einer der großen propagandistischen Aspekte der Programmierung ist, dass sie für die Wiederverwendung von Code und / oder Modulen entworfen werden sollte. Mit anderen Worten, Funktionalität sollte in diskrete wiederverwendbare Teile aufgeteilt werden. Wenn Sie Code haben, der tatsächlich etwas tut und eine Anforderung erfüllt, besteht das Argument nicht darin, dass der Code neu geschrieben werden muss, sondern vielmehr in einen Zustand, in dem er wiederverwendet werden kann / p>
Das bedeutet nicht, dass Sie keine großen Code-Teile wegwerfen und ersetzen sollten. Tatsächlich sagt uns die Idee des Refactorings, genau das zu tun. Die Idee ist jedoch auch, dass wir währenddessen Tests durchführen und verbessern sollten, um ein kompatibles Verhalten und eine erhöhte Wiederverwendbarkeit und Modularisierung sicherzustellen.
Wenn Sie sogar ein Modul verwenden können, das eine Anforderung erfüllt, und es in Version 2 erneut verwenden können, haben Sie die Codebasis definitionsgemäß nicht verworfen und neu gestartet . Und warum solltest du, wenn auch in schlechtem Code, normalerweise nur ein paar Optimierungen benötigen, um es in guten Code aufzuräumen? Ganz zu schweigen von den Perlen des guten oder sogar "guten" Codes, die im Projekt existieren.
Disclaimer: Ich arbeite an einer Universität, wo der Zweck von Software darin besteht, die Gültigkeit neuer Ideen zu begründen oder zu widerlegen. Während einige Akademiker seit über 20 Jahren dieselbe Software verwenden (Beispiele: der Glasgow Haskell Compiler und die ACL2 Theorembeweiser , viele Akademiker verlassen alte Projekte und starten regelmäßig neue Projekte.Für viele von uns ist die richtige Faustregel Solange die Software produktiv bleibt, sollten Sie das Refactoring verbessern und nicht von vorn beginnen. "Produktiv" bedeutet verschiedene Dinge in verschiedenen Kontexten, aber einige Beispiele sind:
Für uns kann eine vollständige Neufassung gerechtfertigt sein, wenn sie die Möglichkeit bietet, neue Ideen auszuprobieren . Ein riskanterer Schritt für eine vollständige Neufassung ist es, eine größere Wirkung zu erzielen. Zum Beispiel sind wir dabei, einen Optimierer in Haskell neu zu schreiben (er wurde in Objective Caml geschrieben), weil wir durch das Schreiben in Haskell mehr Leute dazu bringen können, ihn zu benutzen, und wir können seine Glaubwürdigkeit durch die Verwendung in einem großen System etablieren Open-Source-Aufwand. Aber es ist immer noch ein riskantes Unterfangen für uns, weil es schwierig ist, Papiere über alte Ideen zu veröffentlichen, die in neuen Implementierungen neu geschrieben wurden.
Die kurze Version ist das eine vollständige Neufassung ist fast nie gerechtfertigt .
Der Grund, warum Sie es neu schreiben wollen, ist, weil die Probleme, die Sie jetzt sehen, nicht vorhergesehen wurden, als es geschrieben wurde, es könnte zwei Gründe dafür geben 1. Es war nicht beabsichtigt zu tun, was es gerade macht oder 2. Es war einfach ein Fehler.
Geben Sie ein sehr gründliches Denken, wenn Sie in der Lage sind, all die Dinge vorauszusehen, die es erfordern könnte.
Nur dann überschreiben Sie es. Aber im Allgemeinen wird der am besten geschriebene und gut verwaltete Code nur refactoring benötigt.
Prost, Pavan
Wenn es bereits in einer modernen Sprache ist, refactor statt neu schreiben.
Wenn ich eine Cobol-App hätte und mein Mainframe irgendwann weg wäre, wäre es an der Zeit, es neu zu schreiben. Wenn ich eine alte App in FoxPro gefunden habe und wir noch die Funktionalität benötigen, schreiben Sie sie neu.
Aber wenn es in Java ist, egal wie schlecht es ist, refaktorieren Sie ein Bit nach dem anderen. Es wird ehrlich weniger weh tun.
Tags und Links project-management code-review rewrite