Woher weißt du, dass du den robustesten Code schreibst, der ohne Überarbeitung möglich ist?
Ich denke zu viel über jeden möglichen Weg nach, den mein Code einschlagen kann, und es fühlt sich manchmal wie Zeitverschwendung an. Ich denke, es hängt von der Art des Programms ab, das Sie schreiben, aber ich möchte nicht zu viel Zeit in Anspruch nehmen, wenn ich Situationen in Betracht ziehe, die niemals eintreten werden.
self-improvement
programming-practices
Fran Sevillano
quelle
quelle
Antworten:
Was halten Sie von robustem Code? Code, der bereits zukunftssicher und so leistungsfähig ist, dass er mit jeder Situation umgehen kann? Falsch, niemand kann die Zukunft vorhersagen! Und wieder falsch, denn es wird ein kompliziertes, unhaltbares Durcheinander.
Ich verfolge verschiedene Prinzipien: In erster Linie YAGNI (noch) und KISS , damit ich keinen unnötigen Code schreibe. Das beugt auch Überentwicklungen wirksam vor. Ich überarbeite die Anwendung, wenn Erweiterungen benötigt werden. Mit modernen Refactoring-Tools können Sie ganz einfach Schnittstellen erstellen und Implementierungen später bei Bedarf austauschen.
Dann versuche ich, den Code, den ich schreibe, so robust wie möglich zu gestalten. Dazu gehört, möglichst viele Pfade, die das Programm nehmen kann (und auch Zustände), und ein wenig spartanische Programmierung zu eliminieren . Eine große Hilfe sind "atomare" Funktionen / Methoden, die sich nicht auf externe Zustände stützen oder das Programm zumindest nicht in einem inkonsistenten Zustand belassen, wenn sie fehlschlagen. Wenn Sie das gut machen, ist es auch sehr unwahrscheinlich, dass Sie jemals mit Spaghetti-Code enden, und es ist auch ein Segen für die Wartbarkeit. Beim objektorientierten Entwurf sind die SOLID- Prinzipien auch ein guter Leitfaden für robusten Code.
Ich habe wirklich herausgefunden, dass Sie häufig die Komplexität reduzieren können, beispielsweise durch kombinatorische Explosionen von Programmpfaden oder -zuständen, indem Sie sich gründlich überlegen, wie Sie diesen Pfad als möglichst geraden Pfad gestalten können. Versuchen Sie, die möglichen Kombinationen auf ein Minimum zu beschränken, indem Sie die beste Reihenfolge Ihrer Unterprogramme auswählen und sie für diesen Zweck entwerfen.
Robuster Code ist meistens einfacher und sauberer Code, aber Einfachheit ist eine Eigenschaft, die nicht immer leicht zu erreichen ist. Dennoch solltest du danach streben. Schreiben Sie immer nur den einfachsten Code und erhöhen Sie die Komplexität nur, wenn Sie keine andere Wahl haben.
Einfachheit ist robust, Komplexität ist fragil.
Komplexität tötet.
quelle
Ich versuche ein Gleichgewicht zu halten und konzentriere mich auf
Es ist ein unscharfer Grenzbereich - manchmal schaffe ich es, nicht benötigte Arbeiten zu erledigen, manchmal schaffe ich es nicht, etwas zu tun, was sich später als notwendig herausstellt. Wenn die Fehler nicht groß sind, geht es mir gut. Ich bemühe mich jedenfalls, aus meinen Fehlern zu lernen.
quelle
Der Unterschied zwischen robuster und Überentwicklung ist der Unterschied zwischen dem angemessenen Umgang mit allen möglichen Anwendungsfällen, auch den bizarren und Rand-Anwendungsfällen, die NICHT vorkommen SOLLTEN. Wenn ich es anmutig sage, betrete der Benutzer einen bizarren Ausnahmefall oder gerät in eine Situation, in der eine nicht unterstützte oder nicht spezifizierte Funktion erforderlich ist, die nicht definiert wurde, und der Code wird ordnungsgemäß ohne Absturz beendet oder informiert den Benutzer über nicht unterstützte Funktionen.
Overengineering hingegen kann in den Bereich der vollständigen Implementierung von Funktionen fallen, die nicht benötigt oder angefordert wurden (einige Funktionen werden vom Kunden zwar benötigt, wurden aber nie angefordert!) ODER es kann definiert werden, indem ein zu komplexes Design oder ein zu komplexes Design abgeleitet wird Code, um ein relativ einfaches Problem zu behandeln.
quelle
1) Anforderungen abrufen.
2) Schreiben Sie den Mindestcode, um die Anforderungen zu erfüllen. Wenn etwas nicht eindeutig ist, machen Sie eine fundierte Vermutung. Wenn es sich um Super - mehrdeutig, gehen Sie zu 1 zurück.
3) Zum Testen senden.
4) Wenn die Tester es für gut halten, dokumentieren Sie die Genehmigung. Wenn etwas nicht stimmt, gehe zurück zu 1.
Konzentrieren Sie sich darauf, Tests zu bestehen, ohne sie vorherzusagen. Wenn Sie keine Tester haben ... holen Sie sich Tester! Sie sind nicht nur für die Überprüfung der Code-Korrektheit wichtig, sondern für den gesamten Entwicklungsprozess.
quelle
Halten Sie zunächst die Daten so weit wie möglich normalisiert (nicht redundant). Wenn die Daten vollständig normalisiert sind, kann keine einzelne Aktualisierung der Daten zu Inkonsistenzen führen.
Sie können die Daten nicht immer normalisieren, mit anderen Worten, Sie können Redundanz möglicherweise nicht beseitigen. In diesem Fall kann es zu inkonsistenten Zuständen kommen. Das Ding, das zu tun ist, ist , die Inkonsistenz zu tolerieren und sie regelmäßig mit einer Art Programm zu reparieren, das darüber hinwegfegt und es repariert.
Es besteht eine starke Tendenz, zu versuchen, die Redundanz mithilfe von Benachrichtigungen eng zu verwalten. Diese sind nicht nur schwer auf ihre Richtigkeit zu überprüfen, sondern können auch zu enormen Ineffizienzen führen. (Ein Teil der Versuchung, Benachrichtigungen zu schreiben, entsteht, weil sie in OOP praktisch gefördert werden.)
Im Allgemeinen ist alles, was von der zeitlichen Abfolge von Ereignissen, Nachrichten usw. abhängt, anfällig und erfordert Tonnen von defensiver Codierung. Ereignisse und Meldungen sind für redundante Daten charakteristisch, da sie Änderungen von einem Teil zum anderen übermitteln, um Inkonsistenzen zu vermeiden.
Wie gesagt, wenn Sie über Redundanz verfügen müssen (und die Chancen stehen ziemlich gut), ist es am besten, wenn Sie in der Lage sind, a) dies zu tolerieren und b) es zu reparieren. Wenn Sie versuchen, Inkonsistenzen nur durch Nachrichten, Benachrichtigungen, Trigger usw. zu verhindern, wird es Ihnen sehr schwer fallen, sie robust zu machen.
quelle
Fehler werden auf dem Weg dorthin auftauchen, aber sie werden (zum Glück) lokalisiert und werden (in den meisten Fällen) sehr früh im Test auftauchen. Der andere Vorteil der Wiederverwendung besteht darin, dass der Kunde / Anrufer den größten Teil der Fehlerprüfung / des Gerüsts mit dem von der Implementierung mitgebrachten Aufwand einsparen kann.
Ihre Tests definieren dann die Fähigkeiten und die Robustheit Ihres Programms. Fügen Sie weitere Tests hinzu, bis Sie mit den Erfolgsquoten und Eingaben zufrieden sind. nach Bedarf verbessern, erweitern und verstärken.
quelle
Ich mache diese Unterscheidung, indem ich Code mit genau definierten, aber nicht unbedingt optimalen Verhaltensweisen für sehr unwahrscheinliche Ausführungspässe schreibe. Wenn ich zum Beispiel ziemlich sicher bin (nachgewiesen, aber nicht getestet), dass eine Matrix eindeutig ist, füge ich eine Zusicherung oder Ausnahme in das Programm ein, um den Status zu testen, schreibe aber keinen eigenen Codepfad dafür. Dadurch wird das Verhalten definiert, aber suboptimal.
quelle
Robustheit: Der Grad, in dem ein System bei ungültigen Eingaben oder stressigen Umgebungsbedingungen weiter funktioniert. (Code Complete 2, S. 464)
Die wichtige Frage hierbei ist, wie wichtig Robustheit für Sie ist. Wenn Sie Facebook sind, ist es sehr wichtig, dass Ihre Website weiterhin funktioniert, wenn jemand Sonderzeichen in die Eingabe eingibt, und dass Ihr Server nicht ausfällt, wenn 100 Millionen Benutzer gleichzeitig angemeldet sind. Wenn Sie ein Skript schreiben, um eine allgemeine Operation auszuführen, die nur Sie ausführen, ist Ihnen das egal. Dazwischen gibt es viele Levels. Ein Urteil darüber zu fällen, wie viel Robustheit Sie benötigen, ist eine der wichtigen Fähigkeiten, die ein Entwickler erlernen sollte.
Das Prinzip von YAGNI gilt für das Hinzufügen von Funktionen, die ein Programm möglicherweise benötigt. Dieses Prinzip gilt jedoch nicht für die Robustheit. Programmierer neigen dazu, die Wahrscheinlichkeit zu überschätzen, dass eine bestimmte zukünftige Erweiterung benötigt wird (insbesondere wenn es eine coole ist), aber sie unterschätzen die Wahrscheinlichkeit, dass etwas schief geht. Wenn sich herausstellt, dass eine ausgelassene Funktion später benötigt wird, kann der Programmierer sie später schreiben. Wenn sich herausstellt, dass eine ausgelassene Fehlerprüfung erforderlich ist, kann der Schaden verursacht werden.
Daher ist es eigentlich besser, sich auf die Suche nach ungewöhnlichen Fehlerzuständen zu begeben. Aber es gibt ein Gleichgewicht. Einige der Dinge, die in dieser Bilanz berücksichtigt werden müssen:
Vergessen Sie nicht, dass die Benutzer versuchen können und werden, Ihr Programm auf unerwartete Weise zu verwenden. Es ist besser, wenn etwas Vorhersehbares passiert, wenn sie es tun.
Verwenden Sie als letzte Verteidigungslinie die Zusicherung oder das Herunterfahren. Wenn etwas passiert, mit dem Sie nicht umgehen können, fahren Sie das Programm herunter. Das ist normalerweise besser, als dem Programm zu erlauben, etwas Unvorhersehbares zu tun.
quelle