Ein großer Teil meines Codes weist einen großen Konstruktionsfehler auf. Beenden Sie es oder reparieren Sie es jetzt? [geschlossen]


186

Ich bin ein Gymnasiast, der mit einem Freund von mir an einem C # -Projekt mit ungefähr dem gleichen Können wie ich arbeitet. Bisher haben wir ungefähr 3.000 Codezeilen und 250 Testcodezeilen in einem Bereich von 100 Commits geschrieben. Aufgrund der Schule habe ich das Projekt für ein paar Monate verschoben und kürzlich konnte ich es wieder aufnehmen.

Als ich es wieder aufgegriffen hatte, wurde mir klar, dass der von mir geschriebene Code schlecht gestaltet war, z. B. die Einbeziehung übermäßiger Threads in den Renderer, die schlechte Verhinderung von Race-Bedingungen bei der Interaktion zwischen emulierter CPU, GPU und Spielekassette sowie einfach redundanten und verwirrenden Code.

Das Problem ist, dass ich noch nicht einmal die Hauptfunktionalität meines Programms abgeschlossen habe, so dass ich nicht wirklich überarbeiten kann, und ich fühle mich entmutigt, mir vollkommen bewusst zu sein, dass das Design meines Codes fehlerhaft ist. Gleichzeitig möchte ich das Projekt nicht aufgeben; Es wurden erhebliche Fortschritte erzielt, und die Arbeit darf nicht vergeudet werden.

Ich habe das Gefühl, eine Reihe von Möglichkeiten zu haben: Die Funktionalität einfach zu beenden, indem ich das schlechte Design umgehe und dann alles umgestalte, sobald alles funktioniert, alles anhält und daran arbeite, alles zu entwirren, bevor der Rest der Funktionalität abgeschlossen werden kann, und das Projekt startet Überall, so dass es wieder frisch in meinem Kopf ist oder das Projekt aufgrund seiner übermäßigen Größe endgültig aufgibt (im Wesentlichen "Zurück zum Zeichenbrett").

Was ist der Grund, um mich wieder auf den richtigen Weg zu bringen, basierend auf den Erfahrungen anderer in solchen Projekten? Aus den Antworten auf dieser Website geht der allgemeine Konsens hervor, dass das Umschreiben im Allgemeinen nicht erforderlich ist, aber eine verfügbare Option ist, wenn der Code nicht ohne übermäßige Kosten gepflegt werden kann. Ich würde dieses Projekt gerne weiter verfolgen, aber so wie es aussieht, ist mein Code nicht gut genug für mich, um fortzufahren, und ein Gefühl der Mutlosigkeit hindert mich daran, fortzufahren.


13
Im Ernst: Ein großer Konstruktionsfehler in seinen Produkten hat Larry Ellison nie aufgehalten. Warum sollte es dich stören?
Pieter Geerkens

54
Arbeit wurde nicht verschwendet. Es hat Sie zu einem besseren Programmierer gemacht.
Sampathsris

10
Dies trifft im Moment möglicherweise nicht auf Sie zu, aber wenn Sie in Zukunft etwas schreiben, das Sie professionell pflegen möchten, sollten Sie niemals ein umfangreiches Umschreiben durchführen .
Gcampbell

8
@JoeBlow "100% der Software wird schnell völlig unbrauchbar und muss von Grund auf neu erstellt werden." Diese Aussage ergibt keinen logischen Sinn. Sie sagen mir, dass die Software, die ich jeden Tag verwende, völlig nutzlos ist und von Grund auf neu erstellt werden muss?
oldmud0

10
"Nun ja, natürlich. Niemand verwendet OS9 oder Windows3. Software ist bemerkenswert temporär." Sie irren sich wie immer trotz Ihres Vertrauens! Der Windows NT-Kernel, der in NT 3.1 eingeführt wurde, ist das Kernstück von Windows 10. Seit 20 Jahren wurde Windows nicht mehr vollständig neu geschrieben.
Leichtigkeitsrennen im Orbit

Antworten:


273

Wenn ich in deinen Schuhen stecke, würde ich es wahrscheinlich so versuchen:

  • Beenden Sie zunächst das aktuelle Projekt - zumindest teilweise - so bald wie möglich, jedoch in einem funktionierenden Zustand . Möglicherweise müssen Sie Ihre ursprünglichen Ziele reduzieren und überlegen, welche Mindestfunktionalität Sie in "Version 1.0" wirklich benötigen.

  • Dann, und erst dann , überlegen Sie sich, ob Sie von Grund auf neu schreiben möchten (nennen wir dies "Version 2.0"). Vielleicht können Sie einen Teil des Codes von V1.0 wiederverwenden. Vielleicht haben Sie nach einem erneuten Einschlafen die Entscheidung getroffen, V1.0 umzugestalten und das meiste davon zu speichern. Treffen Sie diese Entscheidung jedoch erst, wenn Sie über keinen "Proof of Concept V1.0" verfügen.

Ein Arbeitsprogramm "1.0" ist etwas, das Sie anderen zeigen können, auch wenn der Code schlecht ist (worum sich außer Ihnen niemand kümmert). Wenn Sie in der Mitte der Erstellung von V2.0 feststellen, dass Ihnen die Zeit ausgeht, haben Sie immer noch V1.0 als Teilerfolg, was Ihrer Moral erheblich zuträglich ist. Wenn Sie jedoch nicht zuerst V1.0 fertig stellen, ist die Wahrscheinlichkeit groß, dass Sie V2.0 nie fertig stellen, denn wenn Sie zur Hälfte fertig sind, wird es einen Punkt geben, an dem Sie mit dem Design wieder unzufrieden sind, und dann? Werden Sie V2.0 wieder verlassen und an V3.0 arbeiten? Es besteht ein hohes Risiko, in diesen Kreis zu geraten, der niemals endet.

Nutzen Sie dies lieber als Gelegenheit, um zu lernen, wie Sie Zwischenziele erreichen, anstatt zu lernen, wie Sie Projekte in einem unvollendeten Zustand hinter sich lassen.


71
Man könnte sich auch eine funktionierende Version 1.0 ansehen, um mehr über den Refactoring-Prozess zu erfahren.
jpmc26

20
Diese. Ich finde oft mehr als eine Reihe von Designfehlern / Designbeschränkungen / Anforderungsaktualisierungen, während ich mich vom Nichts zum ersten funktionierenden Prototyp weiterentwickle. Das Erreichen eines tatsächlichen Arbeitszustands ist wichtig.
Eugene Ryabtsev

14
Nach meiner Erfahrung kommen schlechte Design- und / oder Entwicklungsentscheidungen normalerweise auf, wenn das Projekt wächst. Wie die Antwort vermuten lässt, ist es am besten, eine funktionierende Version 1.0 zu haben, anstatt einen Neustart von Grund auf durchzuführen. Sie können diese Version 1.0 dann als Basis für die nächste Version verwenden.
Keale

9
Wenn Sie ein Projekt abschließen, können Sie potenzielle Probleme erkennen, auf die Sie noch nicht gestoßen sind, und Ihnen möglicherweise tatsächlich zeigen, dass einige Dinge, die Sie für Probleme halten, möglicherweise nicht so groß sind, wie Sie glauben.
CaffeineAddiction

9
Der letzte Satz ist erstaunlich:Better take this as an opportunity to learn how to achieve intermediate goals, instead of an opportunity to learn how to leave projects in an unfinished state behind.
Brandon

119

Fertige IT-Projekte, auch fehlerhafte, sind viel besser als unfertige.

Unvollendete können dir auch viel beibringen, aber nicht so viel wie vollendete.

Sie können es jetzt vielleicht nicht sehen, aber Sie bekommen eine enorme Menge an Wert, wenn Sie mit sogar fehlerhaftem Code arbeiten.

Meine Stimme geht für die Fertigstellung und dann vielleicht Refactoring - wenn nötig. Wenn Sie anfangen, mit mehr Projekten zu arbeiten, werden Sie feststellen, dass der Teil, der "umgestaltet werden sollte", überraschenderweise oft jahrelang unberührt bleibt, während andere Teile erweitert werden.

Aus Sicht der Beschäftigung erhalten Sie in den meisten Fällen mehr Anerkennung für ein abgeschlossenes Projekt.


11
Ehrlich gesagt, in nicht trivialen Projekten gibt es immer ein paar Fehler. Listen Sie sie auf und korrigieren Sie sie in der nächsten Version. Dafür gibt es Release Notes.
RedSonja

56

Ich würde das Projekt gerne von vorne beginnen.

Du bist Student und lernst noch. Dies versetzt Sie in eine ganz andere Position als die Frage, mit der Sie verbunden sind.

  • Sie haben keine professionelle Verantwortung für Ihren Code. Wenn Sie jetzt das gesamte Projekt löschen und weggehen, würden Sie keine Auswirkungen haben. Dies ist ein großer Vorteil für einen Entwickler. In der Frage, die Sie verlinkt haben, versuchen diese Entwickler, Software zu warten, für die die Leute Geld bezahlen, und selbst kleine Fehler können bei Kunden große Probleme verursachen, was es gefährlich macht, von Grund auf neu zu schreiben. Sie haben dieses Problem nicht.

  • Als persönliches Projekt ist dies die perfekte Gelegenheit, neue Dinge auszuprobieren und aus Ihren Fehlern zu lernen. Es ist großartig, dass Sie erkennen, dass Ihr alter Code Probleme hat, denn das bedeutet, dass Sie gelernt haben, wie Sie es besser machen können. Erfahrungen durch Ausprobieren können für Programmieranfänger von unschätzbarem Wert sein.

  • Ihr Projekt ist relativ klein und Sie haben im Grunde keine Tests. Es könnte ein paar Nächte dauern, bis 3000 Zeilen von Grund auf neu geschrieben sind, zumal Sie bereits Ideen haben, was Sie beim nächsten Mal besser machen können.

  • In einer kaputten Codebasis zu arbeiten, belastet Ihre Moral weitaus mehr als ein Umschreiben.

Abgesehen davon ist dies möglicherweise eine gute Gelegenheit, ein modulareres Programm mit Komponententests zu schreiben. Dies erleichtert das Verständnis des Codes, wenn Sie nach einer langen Pause wieder darauf zugreifen, und hilft, Fehler zu vermeiden, die Sie möglicherweise versehentlich aufgrund von Vergesslichkeit einführen.

Schließlich ist hier eine Meinung über die Weisheit, manchmal Schritte rückwärts zu machen, um größere Schritte vorwärts zu machen.


46
Das Umschreiben von scrarch lernt selten aus Fehlern und macht oft einfach neue
Whatsisname

28
Meiner Meinung nach ist es viel wichtiger, ein Projekt abzuschließen, als das perfekte Projekt zu haben. Die Gefahr einer fortwährenden Schleife "Es ist nicht gut genug" ist real.
Pieter B

9
Manchmal muss man aufhören zu graben, wenn man sich ein Loch gräbt. Lernen Sie die vorgestellte Lektion und vereinfachen Sie die zweite Version . Der zweite Systemfehler besteht darin, es schicker und komplexer zu gestalten.
Dale Johnson

15
Es sollte betont werden, dass OP an einem Spielzeugprojekt arbeitet . Ich habe Joels Aufsatz über das Neuschreiben von Grund auf gelesen , und keiner seiner Punkte ist auf diesen Fall anwendbar. OP verkauft seinen Code nicht an die reale Welt, hat keine Frist usw. Wenn sie doppelt so viel Zeit mit Programmieren verbringen, bedeutet dies, dass sie doppelt so viel lernen.
Kevin

6
@whatsisname Sie werden nicht die gleichen Fehler machen. Wie Sie oben sagten, werden sie neue machen, die ihnen neue Dinge beibringen.
Kevin

34

Sie befinden sich wahrscheinlich immer noch im Bereich "Schnelllernen" Ihrer Entwicklung. Es ist gut möglich, dass Sie in ein paar Monaten feststellen werden, dass Ihr neues und großartiges Design in einer Weise schrecklich kaputt ist, die Sie zu Beginn gar nicht bemerkt haben.

Dinge erledigen - das ist das Wichtigste, was Sie lernen müssen. Glauben Sie mir, ich kenne viele Leute (nicht nur Programmierer), die in der Schleife "von vorne anfangen, seit ich so viel gelernt habe, bevor ich mit diesem Projekt angefangen habe" stecken. Das Problem ist, dass es nie endet - bis Sie aufhören, neue Dinge zu lernen, was kein schöner Ort ist :)

Es ist auch wichtig, um irgendetwas tatsächlich beenden zu können. Neu anzufangen ist aufregend, cool, macht Spaß ... aber wenn Sie das nur lernen, werden Sie nie in der Lage sein, etwas zu beenden. Auch das ist keine sehr nützliche Fähigkeit, und es fühlt sich nicht so gut an, als würde man etwas Nützliches (oder Lustiges) machen. Das Leben ist kurz, die Zeit ist begrenzt, und Sie können nicht ohne greifbare Ergebnisse weiter üben - Sie werden davon ganz verrückt. Wenn Sie nicht in der Lage sind, mit der Arbeit zu beginnen, weil Sie sich einfach nicht für einen Ansatz entscheiden können, befinden Sie sich bereits in der Gefahrenzone.

Es wird immer wieder neue Impulse geben. Selbst in einer Lernumgebung ist dies höchstwahrscheinlich eine schlechte Idee. Das bedeutet nicht, dass Sie jeden einzelnen Prototyp zu einer produktionsbereiten Anwendung mitnehmen müssen, weit davon entfernt. Aber Sie müssen zumindest eine funktionierende Prototyp-Phase erreichen - dies wird höchstwahrscheinlich Ihrer Moral zuträglich sein und ist für Entwickler jeglicher Art eine sehr nützliche Eigenschaft. Dinge erledigen . Und der spaßige Teil ist, dass Sie schnell feststellen werden, dass Sie mit Ihrem Prototyp eine Million unterhaltsamerer oder nützlicherer Dinge tun können, anstatt ihn von Grund auf neu zu schreiben - und in vielen Fällen sogar zu überarbeiten. Alles, was Sie tun, hat Kosten - zumindest hätten Sie in der Zwischenzeit etwas anderes tun können.


25

Ich folge der Ideologie "Make it Work, Make it Right, Make it Fast" in der Softwareentwicklung.

  1. Damit es funktioniert: Schreiben Sie die Kernfunktionalität, damit das Projekt verwendet werden kann. Tun Sie, was Sie tun müssen, um alles zum Laufen zu bringen, auch wenn es hässlichen Code bedeutet.
  2. Richtig machen : Beheben Sie Fehler und überarbeiten Sie den Code, damit er leichter zu lesen, zu verstehen und zu warten ist.
  3. Machen Sie es schnell : Optimieren Sie das Programm, um ein ausgewogenes Verhältnis zwischen Geschwindigkeit, Ressourcenverbrauch und Wartbarkeit zu erreichen.

Im Moment haben Sie Schritt 1 noch nicht abgeschlossen. Lassen Sie ihn zuerst funktionieren, und Sie können sich dann Gedanken darüber machen, wie hässlich Ihr Code ist. Ein funktionierendes Produkt zu erstellen, ist für neue Entwickler eine der schwierigsten Aufgaben, da sie so sehr damit beschäftigt sind, ihren Code beim ersten Mal zu perfektionieren, dass sie in der Optimierungshölle stecken bleiben und eigentlich nie fertig werden Implementierung aller Funktionen. Sie müssen lernen, wie Sie all die Sorgen um Refactoring und Optimierung beiseite lassen, damit Sie sich nur darauf konzentrieren können, dass die Software funktioniert. Sobald Sie mehr Erfahrung gesammelt haben, werden Sie auf Anhieb mehr Dinge richtig machen, sodass weniger Refactoring erforderlich ist.

Denken Sie daran: Vorzeitige Optimierung ist die Wurzel allen Übels (siehe diese ausgezeichnete Programmierer.SE-Frage für eine gute Diskussion). Wenn Sie zu viel Zeit damit verbringen, sich Gedanken darüber zu machen, wie Sie Ihren Code verbessern können, stecken Sie in der Analyse-Lähmung . Dies bringt das Projekt zum Erliegen. Es ist besser, das Projekt erst fertigzustellen, bevor Sie versuchen, es zu optimieren.

Um einen großartigen Motivationsredner zu zitieren: Tu es einfach .

Wie immer gibt es eine relevante xkcd:

xkcd optimierung


1
In Open Source können Sie sogar Schritt 0 einfügen, "mach es einfach". Auch wenn es nicht funktioniert, wenn es interessant genug ist, veröffentlichen Sie es, und vielleicht hilft Ihnen jemand bei Schritt 1.
Jörg W Mittag

1
Persönlich mag ich richtigen Code. Ich denke sogar, dass richtiges Design nützlicher sein kann als problematischer Code. Unabhängig von der Reihenfolge von Nr. 1 und Nr. 2 bin ich +1, weil ich die notierte Trennung gerne sehe. Bei größeren Implementierungsproblemen wie der Überprüfung der Race-Bedingungen können solche Probleme häufig behoben werden, ohne dass die API neu entworfen werden muss (welche Funktionen nennen was). Sie können also Fehler beheben, indem Sie sich auf Implementierungsdetails konzentrieren, ohne sich so sehr auf diese konzentrieren zu müssen das funktionierende übergeordnete Design-Zeug. Es kann also (möglicherweise) einen Wert haben, eine (semi?) Funktionierende Codeversion zu haben.
TOOGAM

Ich denke nicht, dass dies zutrifft. Das OP spricht anscheinend über grundlegende Designprobleme . Sie können diese später nicht sicher "patchen".
Leichtigkeitsrennen im Orbit

1
Vergessen Sie nicht die Schritte 0.5, 1.5, 2.5 und 3.5: Machen Sie es lesbar.
candied_orange

23

Schreib es um. Nicht funktionierender Code hat wenig Wert und dreitausend Zeilen sind nicht viel Code. Es wird nicht annähernd so lange dauern, bis Sie den Code geschrieben haben, und es wird viel besser sein. Ich habe oft fünfhundert oder tausend Zeilen schlechten Codes verworfen, und oft dauert das Umschreiben ein Fünftel so lange.

Die meisten Begriffe in Bezug auf "Nicht umschreiben" beziehen sich auf große Systeme, die wichtige Dinge tun und sich ständig ändern, um den sich ändernden Anforderungen gerecht zu werden. Das Umschreiben komplexer Systeme gelingt selten.

Ihre Situation ist genau das Gegenteil. Sie haben eine kleine Anwendung ohne Benutzer, und die einzigen Anforderungen sind die, die Sie implementieren möchten. Also mach weiter und schreibe es neu.


7
Wenn Sie versuchen, einem agilen Entwicklungszyklus zu folgen, ist die Idee, dass Sie, wenn Sie feststellen, dass Sie das falsche Kaninchenloch hinuntergegangen sind, es wegwerfen und eine andere Richtung ausprobieren sollten in der Lage sein, zu einem Commit zurückzukehren, kurz bevor Sie den falschen Weg eingeschlagen haben, damit keine zu große Änderung eintritt. Andernfalls sollten Sie dies als Lektion für ein häufiges Commit verwenden.
Theresa Forster

2
Bei 3k Codezeilen kann es länger dauern, Commits zu überprüfen, als das Ganze neu zu schreiben.
Matthew Whited

Löschen Sie das Git-Repo und fangen Sie von vorne an. Der aktuelle Code ist mit ziemlicher Sicherheit völlig wertlos. Welchen Grund, es auf einem Server zu belassen? - keiner. Klicken Sie auf Löschen.
Fattie

1
@ JoeBlow: kein Grund, das Git-Repo zu löschen. Erstelle einfach eine neue Filiale. Sie können nie sagen, wann Sie auf alte Sachen verweisen möchten.
Kevin Cline

19

Ein Neustart von Grund auf ist in realen Projekten in der Regel eine schlechte Idee, vor allem, weil reale Projekte Fehlerbehebungen enthalten, die einem neuen Entwickler nicht bekannt sind (siehe z. B. " Dinge, die Sie niemals tun sollten" von Joel im Software- Blog).

Nichtsdestotrotz erben Schulprojekte keine solche Geschichte und beginnen in der Regel mit dem Codieren und Entwerfen gleichzeitig mit teilweisem Computerkenntnis und mangelnder Erfahrung. Ich würde Ihre erste Version als Prototyp verwendet als Proof of Concept betrachten , die versagt hat, und ich würde es gerne wegzuwerfen (siehe Was sind die Unterschiede zwischen Wegwerf und evolutionäre Prototypen? Sind für eine Diskussion über Wegwerf vs. evolutionäre Prototyping.)

Das richtige Design ist in Ihrem Kopf gereift und sollte nicht viel Zeit in Anspruch nehmen, um es in Code aufzuschreiben.


12

Ich würde den Vorschlägen, dass das Umschreiben eine schlechte Idee ist, mit Respekt widersprechen.

Im Bereich des Software-Lebenszyklus wird allgemein anerkannt, dass der Zeit- und Arbeitsaufwand für die Korrektur eines Fehlers mit jeder Schicht im Lebenszyklus um eine Größenordnung zunimmt. Das heißt, wenn es 1 Stunde dauert, um einen Fehler auf der Anforderungsstufe zu korrigieren, werden 10 Stunden für das Design, 100 Stunden für das Testen der Codierung und 1000 Stunden für die Fehlerbehebung benötigt. Diese Zahlen mögen empörend klingen, aber sie werden von der Industrie als annähernd korrekt anerkannt. Offensichtlich weniger in einem kleineren Projekt, aber die allgemeine Idee bleibt. Wenn Ihr Projekt einen grundlegenden Konstruktionsfehler aufweist, ist es sinnvoller, dies als Lernerfahrung zu bezeichnen und zurückzukehren, Ihre ursprünglichen Anforderungen zu überprüfen und neu zu entwerfen.

Ich würde auch empfehlen, ein Test Driven Development-Modell mit strukturierten Unit-Tests in Betracht zu ziehen. Sie sind ein Schmerz und scheinen zunächst Zeitverschwendung zu sein, aber ihre Fähigkeit, Fehler aufzudecken, insbesondere wenn sie in den Code eines anderen integriert werden, kann nicht überbewertet werden.


3
Was bedeutet "Industrie akzeptiert"? Was ist die Quelle für die Nummer?
Christian

1
@ Christian Dies scheint die Quelle zu sein: ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20100036670.pdf

1
TDD ist der richtige Weg!
2. Februar,

10

Du hast mich bei diesem Satz verloren:

Das Problem ist, dass ich noch nicht einmal die Hauptfunktionalität meines Programms abgeschlossen habe, so dass ich nicht wirklich überarbeiten kann, und ich fühle mich entmutigt, mir vollkommen bewusst zu sein, dass das Design meines Codes fehlerhaft ist.

Ich glaube an das Prinzip (angegeben in Systemantics ), dass

  • Ein komplexes System, das funktioniert, hat sich ausnahmslos aus einem einfachen System entwickelt, das funktioniert.
  • Ein komplexes System, das von Grund auf neu entwickelt wurde, funktioniert nie und kann nicht gepatcht werden, damit es funktioniert. Sie müssen von vorne beginnen und mit einem funktionierenden einfachen System beginnen.

Das Schreiben eines komplexen Systems umfasst also

  • Ein einfaches System schreiben
  • Stellen Sie sicher, dass es funktioniert

... dh die folgenden Schritte:

  1. Schreiben Sie ein bisschen Code
  2. Testen Sie es, um sicherzustellen, dass es funktioniert
  3. Schreiben Sie etwas mehr Code
  4. Nochmal testen
  5. Usw.

Beachten Sie, dass Schritt 3 Folgendes beinhalten kann:

  1. Schreiben Sie etwas mehr Code
    1. Korrigieren Sie den vorhandenen Code, um ihn für den Neuzugang vorzubereiten
    2. Testen Sie das Refactoring, um sicherzustellen, dass es weiterhin funktioniert
    3. Fügen Sie die neue Funktionalität hinzu

In Schritt 2 "Testen Sie es, um sicherzustellen, dass es funktioniert" müssen Sie möglicherweise etwas umschreiben, wenn dies nicht der Fall ist.

Wenn ich auf einer schlechten Codebasis aufbauen würde, wäre ich nicht geneigt, weitere Funktionen hinzuzufügen. Daher würde ich gerne etwas wie "Vereinfachung der vorhandenen Threading-Implementierung" als nächste zu implementierende Aufgabe einplanen. Angenommen, Sie haben währenddessen Tests durchgeführt, sollten Sie dies als Refactoring-Übung behandeln können. Das Erfolgs- / Austrittskriterium für diese Arbeitsphase wäre:

  • Der Quellcode ist einfacher
  • Und es wurden keine neuen Bugs eingeführt
  • (Und einige alte Bugs beseitigt)

Übrigens bedeutet "Testen, um sicherzustellen, dass es funktioniert" nicht unbedingt "Komponententests". Wenn die Teamstruktur einfach ist, können Sie ein (einfaches) System mithilfe von (einfachen) Systemtests testen (statt Komponententests) .


7

Eines der Probleme, mit denen Sie konfrontiert sind, wenn Sie auf ein Problem wie dieses stoßen, ist, dass Sie emotional an den Code gebunden sind, den Sie bisher auf die eine oder andere Weise geschrieben haben.

Ein Kollege erzählte mir, dass er während seines Studiums ein Programm schrieb, während er Unterricht bei einem berühmten Professor erhielt (ich glaube, es war Dijkstra). Er bat den Professor, sich den Code anzusehen, an dem er seit über einem Monat gearbeitet hatte. Der Professor fragte ihn, ob er ein Backup gemacht habe, er antwortete nein. Der Professor löschte dann seinen gesamten Code und forderte ihn auf, ihn erneut zu schreiben.

Er war sauer, aber 3 Tage später beendete er das Programm mit saubererem Code und weniger Bugs und weniger Codezeilen.

Versuchen Sie, eine ehrliche Schätzung zu machen, welche Option in der für das Projekt verfügbaren Zeit am besten ist.

Die 3 Möglichkeiten sind

  • Löschen Sie es (vollständig, kein Rückblick)
  • Arbeiten Sie weiter im alten Design
  • Refactor-Code, während Sie gehen.

Ich bin seit über 10 Jahren ein professioneller Programmierer und bin zu dem Schluss gekommen, dass die letzte Option meistens die gewählte ist, aber nicht immer die beste.


3
Ich hatte einmal einen Code, der einen Fehler hatte. Ich hatte drei Tage damit verbracht, nach dem Fehler zu suchen, als mein Test ins Wanken geriet, und es gelang mir, den Code zu löschen, keine Sicherungen. Ich habe die gesamte Codebasis aus dem Speicher in einer Nacht neu geschrieben und alle meine Fehler waren verschwunden. Über 3000 Zeilen Codebasis. Also manchmal ist es schlimm. Aber in der Produktion passiert das nie.
Joojaa

6

Es hört sich so an, als ob Ihre Fähigkeiten in diesem Zeitraum erheblich zugenommen haben. Vielleicht hat die Arbeit an diesem Projekt dazu beigetragen. Es wäre fruchtbar, es noch einmal als zielgerichtete Lernerfahrung zu gestalten.

Denken Sie daran, dies ist nicht etwas, was Sie als Arbeitsprogramm für einen Kunden liefern müssen. Es wurde speziell für die Praxis geschrieben. Wenn Sie also nicht lieber Probleme mit dem Versand und fehlerhafte Lieferung üben möchten, befinden Sie sich derzeit in einer Entwicklungsphase, in der sich die Arbeit an Ihren "Design-Muskeln" als fruchtbar erweisen würde.

Konzentrieren Sie sich dabei auf den Entwurfsprozess und die Planung, denken Sie über Ihre vorhandenen Inhalte nach und überlegen Sie, was Sie besser verstehen.


6

Refactor. Refactor. Refactor! REFAKTOR !!!!

Ganz gleich, wie erfahren Sie sind, dies ist ein weit verbreitetes Problem. Sie haben Code geschrieben, etwas gelernt und möchten das neue Wissen auf den alten Code anwenden. Sie möchten den alten Code anhand des neuen Wissens messen.

Das geht einfach nicht. Wenn Sie dies tun, wird Ihre Anwendung / Ihr Spiel niemals abgeschlossen. Versuchen Sie stattdessen, Ihre Zeit dem Projekt zuzuweisen, damit einige Ihrer "Aufgaben" darin bestehen, den fehlerhaften Code zu korrigieren. Angenommen, Sie hatten eine schreckliche Methode, um das Spiel zu speichern. Arbeiten Sie weiter am Spiel selbst, aber finden Sie etwas Zeit, um diese schreckliche Methode umzugestalten (zu ersetzen). Versuchen Sie, die Refaktoren klein zu halten, und es sollte kein Problem sein.

Wenn Sie zu einem großen Teil der Anwendung gelangen, für den ein Refactor erforderlich ist, machen Sie es ernsthaft falsch. Brechen Sie das Refactoring auf kleinere Teile herunter. Versuchen Sie, sieben Stunden mit dem Schreiben von Code und eine Stunde mit dem Refactoring zu verbringen.

Wenn Sie mit dem Projekt fertig sind und die Funktion "Einfrieren" aktiviert haben, können Sie einige Zeit mit der Umgestaltung verbringen. Lassen Sie das Spiel erst einmal laufen, aber versuchen Sie immer noch, einige zu überarbeiten. Das ist das Beste, was Sie tun können.

Es wird immer etwas zu überarbeiten geben.


4

Ich würde sagen, es hängt ein bisschen davon ab, welche Art von Code Sie jetzt haben und wo genau die Probleme liegen. Dh, wenn Ihre Grundlagen gut sind (größtenteils ordentliches Klassendesign, gute Entkopplung / Kohäsion usw., nur ein paar schlechte Entscheidungen wie die von Ihnen erwähnten), dann bekommen Sie auf jeden Fall eine Bare-Bones-1.0 heraus und refaktorieren wie es gibt kein Morgen.

Auf der anderen Seite, wenn es wirklich nur ein Haufen hässlicher, zusammengeschlagener Textdateien ist, die den Compiler irgendwie passieren, ohne erkennbare Struktur usw. (mit anderen Worten, ein Proof-of-Concept-Learning-on-the-Job-Prototyp), dann möchte ich es lieber löschen und von vorne anfangen.

Gehen Sie bei Ihrer nächsten Version agil vor: Legen Sie eine feste Wiederholungszeit fest, z. B. 2 Wochen, oder was auch immer zu Ihrem Zeitplan passt. Setzen Sie sich zu Beginn eines jeden Abschnitts (nennen wir es einen Sprint) Ziele, die in den 2 Wochen erreichbar sind. Mach sie, versuch dein verdammtes Zeug, damit es funktioniert. Stellen Sie Ihre Ziele so ein, dass Sie nach jeweils 2 Wochen etwas haben, das einem Freund gezeigt werden kann, nicht nur eine abstrakte interne Arbeit. Google "Scrum" und "Smart Goal". Dies ist alles sehr einfach, wenn Sie alleine sind, nur ein Stück Papier mit ein paar schnell notierten Aufzählungszeichen.

Wenn Sie das schaffen, ist es gut, von vorne zu beginnen. Wenn Sie genau wissen, dass Sie nach dem Neustart wahrscheinlich enden werden, wo Sie jetzt sind, dann bleiben Sie bei Ihrem Code und bringen Sie ihn zum Laufen.


3

Sie müssen sich in die Lage des Arbeitgebers versetzen.

Für die meisten Personalvermittler sind Sie am wertvollsten, wenn Sie folgendermaßen vorgehen: - Beenden Sie den Vorgang mit 100% -Prüfungen des neuen Codes, den Sie schreiben. - Fügen Sie Tests für den alten (schlecht gestalteten) Code hinzu. - Refactor es zu erreichen, was Sie als Design wollten.

Machen Sie das alles mit einem guten Versionsprozess, Verzweigungen und Tags.

Das Umschreiben ist oft eine sexy Idee, aber es ist oft eine Idee, die Neulinge haben, was im wirklichen Leben ein bisschen gefährlich ist. Zu zeigen, dass Sie eher bereit sind, die Qualität Ihrer bereits geleisteten Arbeit zu verbessern, als von vorne zu beginnen, ist ein gutes Zeichen dafür, dass Sie eine ernsthafte Person sind.

Sie können es natürlich umschreiben, aber dann machen Sie es ein anderes Projekt.


Welcher Arbeitgeber? Das OP ist in der High School und macht ein Haustierprojekt.
Leichtigkeitsrennen im Orbit

Von Anfang an professionell zu agieren kann nicht schlecht sein, und die High School ist meiner Meinung nach nicht allzu weit von einer echten Jobchance entfernt.
Steve Chamaillard

1
"Professionell handeln" hat absolut nichts damit zu tun, ob Sie umgestalten oder nicht.
Leichtigkeitsrennen im Orbit

Es hat in gewisser Weise. Ein Projekt neu zu starten und eine Tonne Arbeit zu verlieren, ist in den meisten Fällen unprofessionell, während die Umgestaltung und damit die Verbesserung langfristig bessere Ergebnisse bringt (in den meisten Fällen).
Steve Chamaillard

Und dies ist keine dieser Zeiten.
Leichtigkeitsrennen im Orbit

3

Nur um einige meiner bisherigen Erfahrungen in den Mix aufzunehmen. Ich arbeite seit über einem Jahr an einem Nebenprojekt, wenn ich ein paar Minuten Zeit habe. Dieses Projekt ging von einer einfachen Testumgebung über eine statische Klasse bis hin zu einem objektorientierten, schlanken Design.

Während all dieser Änderungen habe ich die gleiche Funktionalität des Codes beibehalten, mit Ausnahme von Fehlerkorrekturen und Leistungsvorteilen (muss so schnell wie möglich sein). Dieselbe Codebasis, obwohl überarbeitet, ist dieselbe geblieben, und als solche habe ich sie massiv verbessert, ohne den Code von Grund auf neu schreiben und Zeit verschwenden zu müssen.

Dies bedeutet, dass ich den Code schneller verbessern konnte als zuvor. Es bedeutete auch, dass ich leichter erkennen konnte, was entfernt werden musste, dh unnötige Klassen, und was einfacher bleiben konnte, als mit der alten Idee, die ich noch im Kopf hatte, umzuschreiben.

Daher würde ich raten, Ihren Code zu überarbeiten und von dort aus nach Bedarf Verbesserungen vorzunehmen. Denken Sie jedoch daran, dass Sie die guten Ideen des alten Projekts genau betrachten sollten, um festzustellen, wo sie fehlerhaft sind, wenn Sie sich dazu entschließen, sie von Grund auf neu zu schreiben. Das heißt, Sie kopieren nicht nur alten Code in das neue Projekt.


3

Die Antwort hängt von etwas ab, das ich als "Komplexitätsgrenze" bezeichne. Wenn Sie einer Codebasis mehr und mehr hinzufügen, besteht die Tendenz, dass sie immer komplexer und immer weniger organisiert wird. Irgendwann werden Sie eine "Komplexitätsgrenze" erreichen, an der der Fortschritt sehr schwierig wird. Anstatt zu versuchen, mit Gewalt in Bewegung zu bleiben, ist es besser, ein Backup zu erstellen, neu zu organisieren / zu schreiben und dann weiter voranzukommen.

Ist Ihre Codebasis also so schlecht, dass Sie sich einer Komplexitätsgrenze nähern? Wenn Sie das spüren, nehmen Sie sich etwas Zeit, um aufzuräumen und zu vereinfachen, bevor Sie fortfahren. Wenn die einfachste Möglichkeit zum Bereinigen darin besteht, einige Teile neu zu schreiben, ist dies in Ordnung.


2

Weder? Beide?

Fahren Sie fort, nehmen Sie sich etwas Zeit, um das vorhandene Design zu überarbeiten und neue Funktionen hinzuzufügen.

Wenn Sie über heftige Interaktionen verfügen, ist dies möglicherweise ein guter Ausgangspunkt ("Übermäßige Threads im Renderer" klingen eher nach Ineffizienz als nach Problemen mit der Korrektheit). Sehen Sie nach, ob Sie entweder einen allgemeinen Weg finden, um von Rennen (und möglicherweise Deadlocks) wegzukommen, oder zumindest mehrere spezifische Wege, dies zu tun.

Ich weiß nicht, inwieweit Dinge wie Deadlock und Race Detectors für C # verfügbar sind, aber wenn sie existieren, können sie hilfreich sein, um Probleme zu identifizieren und zu überprüfen, ob Ihre Fixes funktionieren.

Ich finde, dass ich im Allgemeinen mehr motiviert bin, Probleme mit Code zu beheben, der etwas Nützliches bewirkt, als ihn wegzuwerfen und wieder von vorne zu beginnen. Es gibt Fälle, in denen die Entwicklung auf verbrannten Feldern (in Analogie zu „grüner Wiese“ und „brauner Wiese“ ...) zufriedenstellender ist, aber dies ist normalerweise dann der Fall, wenn der bestehende Ansatz so weit davon entfernt ist, dass er nicht mehr falsch ist.


2

Wenn Ihr Code modular aufgebaut ist, sollten Sie in der Lage sein, den Rest des Codes um die schlecht geschriebenen Komponenten herum fertigzustellen und die schlecht geschriebenen Komponenten neu zu schreiben, ohne den Rest des Codes zu beeinflussen.

In diesem Fall liegt es an Ihnen, die schlecht geschriebenen Komponenten neu zu schreiben. Wenn die schlecht geschriebenen Komponenten so schlecht geschrieben sind, dass der fertige Code nicht so funktioniert, wie sie sind, müssen Sie sie neu schreiben, bevor Sie den Rest des Codes fertigstellen können.


2

Die erste Frage, die Sie sich stellen sollten, lautet: "Wie schlimm ist der Fehler?"

Was genau hast du falsch gemacht?

Wenn etwas so schlimm ist, dass Sie Tonnen von Stunden damit verschwenden, das Problem zu lösen, vertrauliche Daten (Passwörter / Kreditkarten) preiszugeben oder eine schwerwiegende Sicherheitslücke zu schaffen, sollten Sie es möglicherweise bearbeiten, aber die meiste Zeit können Sie dies tun Nimm, was du hast, beende es und behebe das Problem später.


Programmierer lieben es, ihre Anwendungen zu verbessern, und möchten, dass sie "so gut wie möglich" sind, aber das ist nicht der richtige Ansatz.

WENN Sie Ihre Anwendung so schnell wie möglich freigeben, auch wenn sie nicht zu 100% fehlerfrei ist, erhalten Sie von anderen ein FEEDBACK , während Sie Zeit haben, die Fehler und andere Probleme für Version 1.1 zu beheben. Andere Leute können Ihnen helfen, die Anwendung so viel besser zu machen, und Sie haben möglicherweise Zeit damit verschwendet , etwas zu tun, das den Leuten vielleicht nicht gefallen hat.

Holen Sie es also in Ihrem Fall heraus, holen Sie sich ein Feedback, und dann können Sie Version 2.0 mit allen Änderungen strukturieren und den Fehler beheben, den Sie haben.


Eine andere Sache, an die man sich erinnern sollte, ist, dass wir uns ständig verbessern. Es gibt ein Sprichwort: Wenn Sie sich Ihren Code von vor einem Jahr ansehen und feststellen, dass er schlecht ist, bedeutet das, dass Sie sich noch verbessern, und das ist eine großartige Sache.


1

Es hängt davon ab, wie durcheinander Ihr Code ist.

  • Wenn Sie echte n00b-Fehler gemacht haben, die Ihren Code übermäßig komplex oder ausführlich machen, würde ich empfehlen, diese Teile neu zu schreiben.

  • Wenn Sie glauben, dass Sie schwerwiegende Fehler haben, die Sie ohnehin beheben müssen, schreiben Sie einige Komponententests, in denen Sie überprüfen können, ob Sie den Fehler behoben haben (... da Sie das Programm noch nicht starten können). Es ist besser, Fehler frühzeitig zu beheben, und es ist definitiv besser, Fehler zu beheben, während Sie sich noch daran erinnern, was der Code tut.

  • Wenn Ihnen nicht gefällt, wie die Methoden heißen, zu welcher Klasse sie gehören oder zu welchen kleinen Dingen sie gehören, verwenden Sie einfach die IDE. (Denken Sie daran, dies ist C #, kein Javascript, Python, Perl, PHP usw.) Wenn Sie an Code arbeiten, der die betroffene Komponente verwendet, und Sie ein klares Bild im Kopf haben, was diese Komponente tun sollte, Refactor es dann, wenn Ihre IDE es schmerzlos macht.

Andernfalls können Sie es zum Laufen bringen und Ihre Fähigkeiten für das nächste Projekt verbessern.


1

Wie andere vorgeschlagen haben, da dies ein persönliches Projekt ist, (noch) kein professionelles Projekt, würde ich ernsthaft über eine Neufassung nachdenken.

Sie können hier jedoch die wissenschaftliche Methode nutzen, indem Sie ein Experiment durchführen. Stellen Sie sich zunächst eine Hypothese vor. Meins wäre: "Es ist wahrscheinlich Zeit für ein Umschreiben." Um Zeit zu sparen, reduzieren Sie die Ausfallkosten und begrenzen Sie die a priori Abweichung ein wenig, bevor Sie weitere Programmierungen vornehmen. Legen Sie einen Zeitraum fest ("Zeitrahmen"). Ich würde vielleicht 4 Wanduhrstunden vorschlagen. Entscheiden Sie sich auch für eine Methode zur Bewertung der Hypothese. Da die Einsätze gering sind, würde ich als Methode vorschlagen, sich einfach zu fragen: "Bin ich froh, dass ich das getan habe?" Beginnen Sie jetzt mit dem Experiment. Wie wird die Hypothese nach dem von Ihnen gewählten Zeitraum bewertet? Sind Sie nach meinem Beispiel froh, dass Sie jetzt mit dem Umschreiben begonnen haben, nachdem Sie 4 Stunden damit verbracht haben? Dann ist es wahrscheinlich die richtige Wahl.

Sie können um alle Ratschläge der Welt bitten, aber es gibt nichts Schöneres, als eine Hypothese empirisch zu testen.

Ein paar Gründe, eine Neufassung als Ihr Experiment in Betracht zu ziehen:

  • Nach meiner Erfahrung macht es normalerweise mehr Spaß. Ein wichtiger Grund, warum in professionellen Situationen oftmals keine Neuschreibungen ausgewählt werden, ist, dass der Spaß weit vom alleinigen Kriterium entfernt ist. Aber Sie sind noch relativ neu in der Codierung, daher ist Spaß wahrscheinlich ein ziemlich wichtiges Kriterium und auch ein Indikator für andere Faktoren, die in diesem frühen Stadium für Sie möglicherweise nicht greifbar sind (Spaß legt nahe, dass Sie mehr lernen usw.).
  • Ihre Erfahrung und wahrscheinlich ein nerviges Gewissen scheinen Ihnen zu sagen, dass ein Umschreiben eine Überlegung wert ist. Hören Sie diese Stimme, wenn es eine gibt. Auch wenn Sie dem Rat nicht folgen, hören Sie wenigstens zu. In Zukunft wird es mehr externe Stimmen geben, und Sie müssen üben, auf Ihren eigenen gesunden Menschenverstand zu hören.
  • Ich vermute, mit einem Rewrite werden Sie Ihren Code eher modularisieren. Wenn Sie Module erstellen, stehen Ihnen wiederverwendbarere und zuverlässigere Komponenten zur Verfügung, die Sie für andere Projekte nutzen können. Vielleicht stellen Sie sogar fest, dass sich das, was wie ein Modul Ihres Hauptprojekts schien, als das interessanteste und wertvollste Stück Code herausstellt, das Sie schreiben.

Etwas zu beenden ist eine gute Idee, aber nicht im luftleeren Raum. Wenn Sie mit einem Umschreiben beginnen, können Sie sich dafür entscheiden, etwas zu beenden, indem Sie ein bestimmtes Untermodul fertigstellen. Sie können dies als erstes Ziel nach dem obigen Experiment festlegen. Die Fertigstellung muss nicht bedeuten, dass Sie Ihr ursprüngliches Hauptprojekt noch fertigstellen. Nachdem Sie ein Modul beendet haben, beenden Sie ein anderes usw., bis Sie den gesamten Bereich Ihres ursprünglichen Projekts neu geschrieben haben, wenn Sie möchten.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.