Ich habe eine beträchtliche Menge an Codierung gelernt, es war jedoch immer in einem wissenschaftlichen Umfeld (nicht in der Informatik), das mir völlig autodidaktisch beigebracht wurde, ohne dass mich jemand in die richtige Richtung führte. Somit war meine Codierungsreise ... chaotisch. Ich habe jetzt festgestellt, dass ich, wenn ich eine Art Programm erstelle, am Ende merke, wie ich es viel eleganter, effizienter und auf eine Weise hätte machen können, die in Zukunft viel flexibler und einfacher zu handhaben ist. Unter bestimmten Umständen bin ich tatsächlich zurückgegangen und habe die Dinge von Grund auf neu aufgebaut, aber normalerweise ist dies praktisch nicht durchführbar. Während die meisten meiner Programme bisher relativ klein waren, scheint es ziemlich unhandlich zu sein, große Programme jedes Mal, wenn Sie etwas erstellen, komplett neu zu schreiben.
Ich frage mich nur, ist das eine normale Erfahrung? Wenn nicht, wie verhindern Sie dies? Ich habe versucht, Dinge im Voraus zu planen, aber ich kann anscheinend nicht alles vorhersehen, bis ich anfange, Code auszuarbeiten.
Antworten:
Dieses Gefühl ist völlig normal und wird erwartet. Es bedeutet, dass Sie lernen. Fast jedes Mal, wenn ich ein neues Projekt beginne, beginne ich in eine Richtung und gestalte es am Ende anders.
Es ist üblich, zuerst einen Prototyp zu entwickeln, bevor man mit der Realität beginnt. Es ist auch üblich , alten Code zu überdenken und Refactoring es. Dies ist einfacher, wenn Ihr Design modular aufgebaut ist - Sie können Teile und Teile auf einmal leicht umgestalten, ohne Ihr altes Design komplett in den Papierkorb werfen zu müssen.
Für manche Menschen ist es hilfreich, zuerst Pseudocode zu schreiben . Andere finden es hilfreich, zuerst Kommentare zu schreiben , die beschreiben, was der Code bewirkt, und dann den Code zu schreiben, sobald die allgemeine Struktur vorhanden ist. Mit diesen beiden Dingen können Sie Ihr Design besser planen und möglicherweise die Notwendigkeit einer Neuschreibung vermeiden.
Wenn Sie Teil eines Teams sind, ist ein Überprüfungsprozess für den Entwurfsprozess von entscheidender Bedeutung. Lassen Sie Ihren Code von jemandem überprüfen, damit Sie lernen, wie Sie Ihr Design verbessern können.
quelle
Dies ist eine sehr häufige Erfahrung
Die meisten Menschen, mit denen ich interagiere, und auch ich selbst fühlen sich so. Ich kann einen Grund dafür nennen, dass Sie mehr über die Domäne und die Tools erfahren, die Sie beim Schreiben Ihres Codes verwenden. Dadurch erkennen Sie viele Verbesserungsmöglichkeiten, nachdem Sie Ihr Programm bereits geschrieben haben.
Der andere Grund ist, dass Sie möglicherweise eine Vorstellung von der idealen Clean-Code-Lösung haben und sich dann die reale Welt und ihre chaotischen Einschränkungen in den Weg stellen. Dies zwingt Sie dazu, fehlerhafte Workarounds und Hacks zu schreiben, die Sie möglicherweise unzufrieden machen.
"Jeder hat einen Plan, bis er ins Gesicht geschlagen wird."
Was tun?
Bis zu einem gewissen Grad müssen Sie lernen zu akzeptieren, dass Ihr Code niemals perfekt sein wird. Eine Sache, die mir dabei geholfen hat, ist die Einstellung "Wenn ich den Code hasse, den ich vor einem Monat geschrieben habe, bedeutet das, dass ich gelernt habe und ein besserer Programmierer geworden bin".
Eine Möglichkeit, das Problem zu beheben, besteht darin, ständig nach möglichen Verbesserungen Ausschau zu halten, während Sie kontinuierlich arbeiten und umgestalten. Stellen Sie sicher, dass Sie ein ausgewogenes Verhältnis zwischen dem Refactoring und dem Hinzufügen neuer Funktionen / dem Beheben von Fehlern herstellen. Dies wird bei großen Designproblemen nicht helfen, aber im Allgemeinen erhalten Sie eine ausgefeiltere Codebasis, auf die Sie stolz sein können.
quelle
Lernen Sie Refactoring - die Kunst, Code schrittweise zu verbessern . Wir alle lernen die ganze Zeit, daher ist es üblich zu erkennen, dass der von Ihnen selbst geschriebene Code besser geschrieben werden könnte.
Sie sollten jedoch in der Lage sein, den vorhandenen Code zu transformieren, um diese Verbesserungen anzuwenden, ohne von vorne beginnen zu müssen.
quelle
Wenn Sie ausgezeichnete statische Anforderungen haben, diese gut verstehen und Zeit für detaillierte Analysen haben, haben Sie die Möglichkeit, ein gutes Design zu entwickeln, mit dem Sie nach Abschluss der Analyse immer noch zufrieden sind.
Selbst in diesem glückseligen Fall lernen Sie möglicherweise neue Sprachfunktionen, die zu einem besseren Design beigetragen hätten.
Normalerweise werden Sie jedoch nicht so viel Glück haben: Die Anforderungen sind weniger als hervorragend und unvollständig, und obwohl Sie dachten, Sie hätten sie verstanden, stellt sich heraus, dass es Bereiche gibt, für die Sie ungültige Annahmen getroffen haben.
Die Anforderungen ändern sich dann, wenn die Benutzer einen Blick auf Ihre ersten Ergebnisse werfen. Dann ändert sich etwas, das die Nutzer nicht kontrollieren, zB das Steuerrecht.
Alles, was Sie tun können, ist das Entwerfen, vorausgesetzt, die Dinge ändern sich. Überarbeiten Sie, wenn Sie können, aber erkennen Sie, dass Zeit und Budget oft bedeuten, dass Ihr endgültiges Ergebnis nicht so elegant ist, wie es gewesen wäre, wenn Sie am Anfang gewusst hätten, was Sie jetzt wissen.
Im Laufe der Zeit werden Sie besser in die Anforderungen eingehen können, die Sie erhalten, und eine Übersicht darüber erhalten, für welche Teile Ihres Designs wahrscheinlich Flexibilität erforderlich ist, um Änderungen zu absorbieren.
Akzeptieren Sie am Ende jedoch, dass die Änderung konstant ist, und ignorieren Sie den Stich "Ich hätte es besser machen können". Seien Sie stolz und glücklich, dass Sie überhaupt eine Lösung geliefert haben.
quelle
Was Sie tun können, ist, einen Wegwerfprototyp zu erstellen, bevor Sie mit dem "echten" Projekt beginnen. Schnell und dreckig. Wenn Sie dann einen Prototyp erhalten, um ein Konzept zu beweisen, lernen Sie das System kennen und wissen, wie man es richtig macht.
Aber wundern Sie sich nicht, wenn Sie nach N Jahren wieder zu diesem Code zurückkehren und sich "was für ein Durcheinander" überlegen.
quelle
Erinnere dich an dieses Mantra:
Die perfekte Lösung ist nicht immer die ideale Lösung. Die ideale Lösung ist die, die mit dem geringsten Arbeitsaufwand den Status "gut genug" erreicht.
Wenn Sie all diese Fragen mit "Ja" beantworten, ist Ihre Software "gut genug" und es gibt keinen guten Grund, sie von Grund auf neu zu schreiben. Wenden Sie die gewonnenen Erkenntnisse stattdessen auf Ihr nächstes Projekt an.
Es ist völlig normal, dass jeder Programmierer in der Vergangenheit ein paar unordentliche Programme hat. Während meiner Karriere als Softwareentwickler kam es mehrmals vor, dass ich mir Code ansah, fragte mich, "Was für ein Idiot hat dieses Durcheinander geschrieben?", Überprüfte den Versionsverlauf und bemerkte, dass ich es von vor einigen Jahren war.
quelle
Es ist verlockend zu glauben, dass eine perfekte Planung ein perfektes Software-Design / eine perfekte Architektur ergibt. Es stellt sich jedoch heraus, dass dies kategorisch falsch ist. Das hat zwei große Probleme. Erstens stimmen "auf dem Papier" und "der Code" selten überein, und der Grund dafür ist, dass es einfach zu sagen ist, wie es getan werden soll, anstatt es tatsächlich zu tun . Zweitens werden unvorhergesehene Änderungen der Anforderungen erst spät im Entwicklungsprozess sichtbar, über die von Anfang an nicht nachgedacht werden konnte.
Haben Sie von der Agile-Bewegung gehört? Es ist eine Denkweise, bei der wir Wert darauf legen, "auf Veränderungen zu reagieren" und nicht (unter anderem) "einem Plan zu folgen". Hier ist das Manifest (es ist eine kurze Lektüre). Sie können sich auch über Big Design Up Front (BDUF) und die Gefahren informieren.
Leider handelt es sich bei der Unternehmensversion von "Agile" um eine Reihe von Fälschungen (zertifizierte Scrum-Master, schwerer Prozess im Namen von "Agile", Erzwingen von Scrum, Erzwingen einer 100-prozentigen Codeabdeckung usw.), die in der Regel nur zu Änderungen der Prozesse führen, weil Manager denke, Agile ist ein Prozess und eine Silberkugel (von denen es keine ist). Lesen Sie das Agile-Manifest, hören Sie Leuten zu , die diese Bewegung ins Leben gerufen haben, wie Onkel Bob und Martin Fowler, und lassen Sie sich nicht von der unsinnigen Version von "Corporate Agile" verführen.
Insbesondere können Sie in der Regel mit TDD (Test Driven Development) auf wissenschaftlichem Code davonkommen , und es besteht eine gute Chance, dass Ihr Softwareprojekt ziemlich gut ausfällt. Der Grund dafür ist, dass erfolgreicher wissenschaftlicher Code meistens über benutzerfreundliche Schnittstellen verfügt, wobei die Leistung eine untergeordnete (und manchmal konkurrierende) Rolle spielt, sodass Sie mit einem "gierigeren" Design davonkommen können. TDD erzwingt, dass Ihre Software extrem benutzerfreundlich ist , da Sie schreiben, wie die Dinge (im Idealfall) heißen sollen, bevor Sie sie tatsächlich implementieren. Es erzwingt auch kleine Funktionen mit kleinen Schnittstellen , die schnell auf einfache Weise "Eingabe" / "Ausgabe" aufgerufen werden können, und versetzt Sie in eine gute Position für die Umgestaltung falls sich die Anforderungen ändern.
Ich denke, wir sind uns alle einig, dass
numpy
es sich um erfolgreiche Software für wissenschaftliches Rechnen handelt. Ihre Schnittstellen sind klein, super brauchbar und alles spielt gut zusammen. Beachten Sie, dassnumpy
das Referenzhandbuch TDD ausdrücklich empfiehlt: https://docs.scipy.org/doc/numpy-1.15.1/reference/testing.html . Ich habe TDD in der Vergangenheit für SAR-Bildgebungssoftware (Synthetic Aperature Radar) verwendet und kann auch behaupten, dass es für diese bestimmte Domäne sehr gut funktioniert.Vorsichtsmaßnahme: Der Designteil von TDD funktioniert weniger gut in Systemen, in denen ein grundlegendes Refactoring (z. B. die Entscheidung, dass Ihre Software in hohem Maße gleichzeitig ausgeführt werden muss) schwierig ist, wie in einem verteilten System. Zum Beispiel, wenn Sie so etwas wie Facebook zu entwerfen haben , wo man Millionen von gleichzeitigen Benutzern hat, TDD tun (zu fahren Ihr Design) wäre ein Fehler (noch in Ordnung zu verwenden , nachdem Sie haben vorläufiges Design und tun nur „test erste Entwicklungs "). Es ist wichtig, über die Ressourcen und die Struktur Ihrer Anwendung nachzudenken, bevor Sie in den Code springen. TDD wird Sie niemals zu einem hochverfügbaren, verteilten System führen.
In Anbetracht des oben Gesagten sollte es offensichtlich sein, dass ein perfektes Design eigentlich unmöglich zu erreichen ist. Die Jagd nach einem perfekten Design ist also ein Narrenspiel. Man kann sich wirklich nur annähern. Auch wenn Sie denken, Sie können von Grund auf neu gestalten, gibt es wahrscheinlich noch versteckte Anforderungen, die sich nicht gezeigt haben. Darüber hinaus dauert das Umschreiben mindestens so lange , bis der ursprüngliche Code entwickelt ist. Es wird mit ziemlicher Sicherheit nicht kürzer sein, da das neue Design wahrscheinlich eigene unvorhergesehene Probleme hat und Sie alle Funktionen des alten Systems neu implementieren müssen.
Eine weitere zu berücksichtigende Sache ist, dass Ihr Design nur dann wirklich wichtig ist, wenn sich die Anforderungen ändern .Es spielt keine Rolle, wie schlecht das Design ist, wenn sich nichts ändert (vorausgesetzt, es ist für die aktuellen Anwendungsfälle voll funktionsfähig). Ich arbeitete an einer Basislinie mit einer 22.000-Zeilen-Umschaltanweisung (die Funktion war sogar noch länger). War es schreckliches Design? Verdammt ja, es war schrecklich. Haben wir das behoben? Nein, es funktionierte so wie es war und dieser Teil des Systems verursachte nie wirklich Abstürze oder Fehler. Es wurde in den zwei Jahren, in denen ich an dem Projekt beteiligt war, nur einmal berührt, und jemand, Sie haben es erraten, hat einen weiteren Fall in den Schalter eingefügt. Aber es lohnt sich nicht, sich die Zeit zu nehmen, um etwas zu reparieren, das so selten berührt wird, dass dies einfach nicht der Fall ist. Lassen Sie das unvollkommene Design so sein, wie es ist, und wenn es nicht kaputt ist (oder ständig bricht), reparieren Sie es nicht. Vielleicht könnten Sie es besser machen ... aber wäre es eine umschreibung wert? Was wirst du gewinnen?
HTH.
quelle
Ich stimme der Antwort von Andreas Kammerloher voll und ganz zu, aber ich bin überrascht, dass noch niemand vorgeschlagen hat, einige bewährte Codierungsmethoden zu erlernen und anzuwenden. Natürlich ist dies kein Wundermittel, aber wenn Sie eine offene Herangehensweise, Entwurfsmuster, das Verstehen, wann Ihr Code riecht usw. verwenden, werden Sie zu einem besseren Programmierer. Untersuchen Sie, wie Bibliotheken, Frameworks usw. am besten genutzt werden. Es gibt noch viel mehr, ich kratze nur an der Oberfläche.
Es bedeutet nicht, dass Sie Ihren alten Code nicht als totalen Müll ansehen (Sie werden in den ältesten Programmen sogar noch mehr Müll sehen als ohne dieses Wissen), aber mit jeder neuen Software, die Sie schreiben, werden Sie sehen Sie verbessern. Beachten Sie auch, dass die Anzahl der Best Practices für die Codierung mit der Zeit zunimmt. Einige ändern sich einfach, sodass Sie tatsächlich nie die Perfektion erreichen. Akzeptiere das oder ganz den Weg.
Eine weitere gute Sache ist eine Coderevision. Wenn Sie alleine arbeiten, ist es einfach, Ecken zu schneiden. Wenn eine zweite Person Ihren Code überprüft, kann sie darauf hinweisen, wo Sie diese bewährten Methoden nicht befolgen. Auf diese Weise erstellen Sie besseren Code und lernen etwas.
quelle
Um die anderen hervorragenden Antworten hier zu ergänzen, finde ich es hilfreich zu wissen, wohin Sie möchten .
Es kommt selten vor, dass ein wesentlicher Teil des Refactorings selbst durchgeführt wird. Bei der Arbeit an den einzelnen Bereichen der Codebasis können Sie jedoch häufig kleinere Refactoring-Vorgänge ausführen. Und wenn Sie ein Ziel vor Augen haben, können Sie diese Gelegenheiten nutzen, um Schritt für Schritt in die richtige Richtung zu gehen.
Es kann lange dauern, aber die meisten Schritte werden den Code verbessern und das Endergebnis wird es wert sein.
Auch das Gefühl, dass Sie es besser machen könnten, ist ein gutes Zeichen ! Es zeigt, dass Ihnen die Qualität Ihrer Arbeit am Herzen liegt und dass Sie sie kritisch bewerten. Sie lernen also wahrscheinlich und verbessern sich. Lassen Sie sich von diesen Dingen nicht beunruhigen - aber hören Sie nicht auf, sie zu tun!
quelle
Sie sind versehentlich auf eine der größten Herausforderungen (Abenteuer) der Menschheit gestoßen, die Brücke zwischen Mensch und Maschine. Die Brücke zwischen Mensch und physischer Struktur, zum Beispiel im Bauwesen, besteht seit etwa 200 Jahren oder länger.
Da die Softwareentwicklung erst in den 90er Jahren zum Mainstream wurde, ist sie ungefähr 30 Jahre alt. Wir haben gelernt, dass es nicht so sehr eine Ingenieurdisziplin als eine Sozialwissenschaft ist, und wir haben gerade erst begonnen.
Ja, Sie werden versuchen, TDD, Refactoring, funktionale Programmierung, das Repository-Muster, Event-Sourcing, MV etwas, Java Script (<- Tun Sie das, es ist verrückt), Modellbindung, No SQL, Container, Agile, SQL (<- Tun Sie das es ist mächtig).
Es gibt keine Lösung. Sogar die Experten greifen immer noch nach Strohhalmen.
Willkommen, und seien Sie gewarnt, es ist ein einsamer Ort. aber absolut faszinierend.
quelle
Ich werde ein wenig gegen den Strich gehen. Dies ist unglaublich häufig , aber nicht akzeptabel . Dies weist darauf hin, dass Sie beim Schreiben des Codes keine guten Methoden zum Organisieren des Codes erkennen. Das Gefühl kommt davon, dass Ihr Code nicht einfach ist .
Ihre Erfahrung war auch lange meine, aber kürzlich (in den letzten paar Jahren) habe ich mehr Code produziert, der mir nicht das Gefühl gibt, dass ich alles wegwerfen muss. Hier ist ungefähr, was ich getan habe:
Mein Code ist jetzt eher "prozedural", was bedeutet, dass er nach den von ihm ausgeführten Aktionen und nicht nach den von ihm verwendeten Datenstrukturen organisiert ist. Ich verwende Objekte in Sprachen, in denen eigenständige Funktionen nicht im laufenden Betrieb ersetzt werden können (C # und Java können Funktionen nicht im laufenden Betrieb ersetzen, Python kann dies). Ich habe die Tendenz, jetzt mehr Utility- Funktionen zu erstellen , die nur eine nervige Kesselplatte aus dem Weg schieben, damit ich die Logik meines Codes tatsächlich lesen kann. (Als ich zum Beispiel alle Elementkombinationen in einer Liste verarbeiten musste, habe ich den Index, der aus der Schleife ausläuft, auf eine zurückgegebene Erweiterungsmethode verschoben
Tuple
s, damit die ursprüngliche Funktion nicht mit diesen Implementierungsdetails überfrachtet wird.) Ich übergebe jetzt viel mehr Dinge als Parameter an Funktionen, anstatt dass eine Funktion auf ein anderes Objekt zugreift, um es abzurufen. (Der Aufrufer holt oder erstellt es stattdessen und übergibt es ihm.) Ich hinterlasse jetzt weitere Kommentare, die Dinge erklären, die nicht nur beim Betrachten des Codes offensichtlich sind , was das Befolgen der Logik einer Methode erleichtert. Ich schreibe Tests nur in begrenzten Fällen, in denen ich mir Gedanken über die Logik von etwas mache, das ich gerade gemacht habe, und ich vermeide es, Verspottungen zu verwenden. (Ich teste mehr Ein- / Ausgänge an isolierten Logikelementen.) Das Ergebnis ist Code, der nicht perfekt ist , der aber eigentlich in Ordnung zu sein scheintsogar 2 oder 3 Jahre später. Der Code reagiert ziemlich gut auf Änderungen. Kleinigkeiten können hinzugefügt oder entfernt oder geändert werden, ohne dass das gesamte System auseinanderfällt.Bis zu einem gewissen Grad, Sie haben zu einer Zeit durchlaufen , wo die Dinge sind ein einziges Chaos , so dass Sie einige Erfahrung geht aus dem. Aber wenn die Dinge immer noch so durcheinander sind, dass Sie alles wegwerfen und von vorne anfangen möchten, stimmt etwas nicht. du lernst nicht.
quelle
Indem Sie sich daran erinnern, dass Ihre Zeit begrenzt ist. Und Ihre zukünftige Zeit ist ebenfalls begrenzt. Ob für die Arbeit oder Schule oder persönliche Projekte, wenn es darum geht , Arbeits Code, müssen Sie sich fragen , „Das ist die beste Nutzung meiner begrenzten und wertvollen Zeit neu schreiben?“. Oder vielleicht "ist dies der verantwortungsvollste Umgang mit meiner begrenzten Zeit"?
Manchmal lautet die Antwort eindeutig Ja . Normalerweise nicht. Manchmal ist es am Zaun, und Sie müssen Ihre Diskretion anwenden. Manchmal ist es eine gute Verwendung Ihrer Zeit, einfach wegen der Dinge, die Sie lernen, indem Sie es tun.
Ich habe viele Projekte, sowohl beruflich als auch privat, die von einem Port / Rewrite profitieren würden. Ich habe auch andere Dinge zu tun.
quelle
Es ist ein ganz normaler Teil des Lernens. Sie erkennen Fehler, wenn Sie gehen.
So wirst du besser und es ist nicht etwas, das du vermeiden solltest.
quelle
Sie können sich die Erfahrung machen, zu wissen, dass der verführerische Drang zum Umschreiben in der Regel unproduktiv ist. Finden Sie ein altes, haariges, unelegantes Open-Source-Projekt von mittlerer Komplexität. Versuchen Sie es von Grund auf neu zu schreiben und sehen Sie, wie Sie es tun.
Irgendwann wird sich Ihr Instinkt von dem Gedanken "Ich könnte dieses System so viel besser umschreiben" zu dem Gedanken "Die Schärfe dieses Systems kann auf eine Komplexität hinweisen, die nicht sofort offensichtlich ist."
quelle