Was Sie hier zu tun haben, ist im Grunde eine Schnittstelle. Durch das Hinzufügen des Verhaltens "Wenn Eingabe ist null
, Eingabe initialisieren" haben Sie die Methodenschnittstelle effektiv erweitert. Anstatt immer eine gültige Liste zu bearbeiten, haben Sie die Eingabe "repariert". Unabhängig davon, ob dies der offizielle oder inoffizielle Teil der Benutzeroberfläche ist, können Sie wetten, dass jemand (höchstwahrscheinlich auch Sie) dieses Verhalten verwenden wird.
Schnittstellen sollten einfach gehalten und relativ stabil sein - insbesondere in einer Art public static
Methode. Sie haben ein wenig Spielraum bei privaten Methoden, insbesondere bei privaten Instanzmethoden. Indem Sie die Schnittstelle implizit erweitern, haben Sie Ihren Code in der Praxis komplexer gemacht. Stellen Sie sich vor, Sie möchten diesen Codepfad nicht wirklich verwenden - vermeiden Sie ihn also. Jetzt haben Sie ein wenig ungeprüften Code, der so tut , als sei er Teil des Verhaltens der Methode. Und ich kann Ihnen jetzt sagen, dass es wahrscheinlich einen Fehler gibt: Wenn Sie eine Liste übergeben, wird diese Liste durch die Methode mutiert. Wenn Sie dies jedoch nicht tun, erstellen Sie eine lokaleListe, und werfen Sie es später weg. Dies ist die Art von inkonsistentem Verhalten, das Sie in einem halben Jahr zum Weinen bringt, wenn Sie versuchen, einen obskuren Fehler aufzuspüren.
Im Allgemeinen ist defensives Programmieren eine ziemlich nützliche Sache. Die Codepfade für die Abwehrprüfungen müssen jedoch wie jeder andere Code getestet werden. In einem solchen Fall verkomplizieren sie Ihren Code ohne Grund, und ich würde stattdessen eine Alternative wie die folgende wählen:
if (rows == null) throw new ArgumentNullException(nameof(rows));
Sie möchten keine Eingabe mit dem rows
Wert null, und Sie möchten den Fehler so schnell wie möglich für alle Anrufer sichtbar machen .
Es gibt viele Werte, mit denen Sie bei der Entwicklung von Software herumspielen müssen. Selbst die Robustheit selbst ist eine sehr komplexe Eigenschaft - ich würde beispielsweise Ihren Defensiv-Check nicht für robuster halten, als eine Ausnahme auszulösen. Ausnahmen sind recht praktisch, um Ihnen einen sicheren Ort zu bieten, an dem Sie es erneut versuchen können - Datenkorruptionsprobleme sind normalerweise viel schwieriger zu verfolgen, als ein Problem frühzeitig zu erkennen und sicher zu behandeln. Letztendlich geben sie Ihnen nur eine Illusion von Robustheit, und dann, einen Monat später, bemerken Sie, dass ein Zehntel Ihrer Termine weg ist, weil Sie nie bemerkt haben, dass eine andere Liste aktualisiert wurde. Autsch.
Achten Sie darauf, zwischen den beiden zu unterscheiden. Defensives Programmieren ist eine nützliche Technik, um Fehler an einer Stelle zu finden, an der sie am relevantesten sind, was Ihre Debug-Bemühungen erheblich unterstützt und mit einer guten Ausnahmebehandlung "hinterhältige Korruption" verhindert. Früh scheitern, schnell scheitern. Auf der anderen Seite ist das, was Sie tun, eher wie "Verstecken von Fehlern" - Sie jonglieren mit Eingaben und machen Annahmen darüber, was der Anrufer gemeint hat. Dies ist sehr wichtig für benutzerbezogenen Code (z. B. Rechtschreibprüfung), aber Sie sollten vorsichtig sein, wenn Sie diesen Code mit Entwicklerbezug sehen.
Das Hauptproblem ist, dass die Abstraktion, die Sie machen, auslaufen wird ("Ich wollte eine Rechtschreibprüfung durchführen, nicht nur!"), Und der Code, mit dem Sie alle Sonderfälle und Korrekturen behandeln können, ist immer noch Ihr Code müssen warten und verstehen, und Code, den Sie testen müssen. Vergleichen Sie den Aufwand, um sicherzustellen, dass eine Nicht-Null-Liste übergeben wird, mit der Behebung des Fehlers, den Sie ein Jahr später in der Produktion haben - es ist kein guter Kompromiss. In einer idealen Welt möchten Sie, dass jede Methode ausschließlich mit ihrer eigenen Eingabe arbeitet, ein Ergebnis zurückgibt und keinen globalen Status ändert. In der realen Welt gibt es natürlich viele Fälle, in denen dies nicht der Fall istDie einfachste und übersichtlichste Lösung (z. B. beim Speichern einer Datei), aber ich finde, dass die Beibehaltung von Methoden "rein", wenn es keinen Grund gibt, den globalen Status zu lesen oder zu manipulieren, den Code viel einfacher zum Nachdenken macht. Es gibt Ihnen auch mehr natürliche Punkte für die Aufteilung Ihrer Methoden :)
Dies bedeutet nicht, dass alles Unerwartete zum Absturz Ihrer Anwendung führen sollte, im Gegenteil. Wenn Sie Ausnahmen gut verwenden, bilden sie natürlich sichere Fehlerbehandlungspunkte, an denen Sie einen stabilen Anwendungsstatus wiederherstellen und dem Benutzer ermöglichen können, ihre Arbeit fortzusetzen (idealerweise unter Vermeidung von Datenverlusten für den Benutzer). An diesen Bearbeitungspunkten sehen Sie Möglichkeiten, die Probleme zu beheben ("Keine Bestellnummer 2212 gefunden. Meinten Sie 2212b?") Oder dem Benutzer die Kontrolle zu geben ("Fehler beim Herstellen einer Verbindung zur Datenbank. Erneut versuchen?"). Selbst wenn keine solche Option verfügbar ist, haben Sie zumindest die Möglichkeit, dass nichts beschädigt wurde. Ich habe angefangen, Code zu schätzen, der verwendet using
und try
... finally
viel mehr als try
...catch
Es bietet Ihnen viele Möglichkeiten, Invarianten auch unter außergewöhnlichen Bedingungen zu erhalten.
Benutzer sollten ihre Daten und Arbeit nicht verlieren. Dies muss noch mit den Entwicklungskosten usw. abgeglichen werden, aber es ist eine ziemlich gute allgemeine Richtlinie (wenn die Benutzer entscheiden, ob sie Ihre Software kaufen oder nicht - interne Software hat normalerweise keinen solchen Luxus). Sogar das Abstürzen der gesamten Anwendung wird weniger problematisch, wenn der Benutzer einfach neu starten und zu dem zurückkehren kann, was er gerade getan hat. Dies ist eine echte Robustheit - Word spart Ihre Arbeit die ganze Zeit, ohne das Dokument auf der Festplatte zu beschädigen, und bietet Ihnen eine Optionum diese Änderungen nach einem Neustart von Word nach einem Absturz wiederherzustellen. Ist es überhaupt besser als ein No Bug? Wahrscheinlich nicht - aber vergessen Sie nicht, dass die geleistete Arbeit, um einen seltenen Fehler zu finden, überall besser ausgegeben werden könnte. Aber es ist viel besser als die Alternativen - z. B. ein beschädigtes Dokument auf der Festplatte, die gesamte Arbeit seit dem letzten Speichern ist verloren gegangen, das Dokument wird automatisch durch Änderungen vor dem Absturz ersetzt, die zufällig Strg + A und Löschen lauteten.