Frage

Ich habe eine Diskussion mit einem meinen Kollegen darüber, wie defensiver Code sein sollte. Ich bin all pro defensive Programmierung, aber Sie müssen wissen, wo zu stoppen. Wir arbeiten an einem Projekt, das von anderen unterhalten werden, aber das bedeutet nicht, dass wir für all die verrückten Dinge überprüfen müssen Entwickler tun könnten. Natürlich könnten Sie das tun, aber das wird einen sehr großen Aufwand, um Ihren Code hinzuzufügen.

Wie Sie wissen, wo die Grenze zu ziehen?

War es hilfreich?

Lösung

Ich weiß nicht, dass es wirklich eine Möglichkeit, dies zu beantworten. Es ist nur etwas, das man aus der Erfahrung lernen. Sie müssen nur sich selbst fragen, wie häufig ein potenzielles Problem ist wahrscheinlich eine Ermessenssache sein und machen. Sehen Sie sich auch, dass Sie nicht unbedingt wurde immer Code defensiv. Manchmal akzeptabel, es ist nur mögliche Probleme in der Dokumentation Ihres Codes zu beachten.

Letztlich aber, ich denke, das ist nur etwas, das eine Person auf ihrer Intuition zu folgen hat. Es gibt keinen richtigen oder falschen Weg, es zu tun.

Andere Tipps

Alles, was ein Benutzer tritt direkt oder indirekt, sollten Sie immer Sanity-Check. Darüber hinaus wird hier ein paar asserts und wird es nicht schaden, aber man kann nicht wirklich viel über verrückten Programmierer Bearbeitung und den Code zu brechen, sowieso! -)

Ich neige dazu, die Menge der Verteidigung zu ändern, die ich auf der Grundlage der Sprache in meinem Code setzen. Heute arbeite ich in erster Linie in C ++, so meine Gedanken in dieser Richtung treiben.

Wenn in C ++ arbeiten kann es nicht genug defensive Programmierung sein. Ich behandle meinen Code als ob ich nukleare Geheimnisse bewacht und jeder andere Programmierer ist, um sie zu bekommen. Behauptet, wirft, Compiler Zeitfehler Vorlage Hacks, Argumentüberprüfung, wodurch Zeiger, in der Tiefe Code-Reviews und allgemeine Paranoia sind alle fair game. C ++ ist eine böse wunderbare Sprache, die ich beide lieben und stark misstrauen.

Ich bin kein Fan der Begriff „defensive Programmierung“. Für mich schlägt es Code wie folgt:

void MakePayment( Account * a, const Payment * p ) {
    if ( a == 0 || p == 0 ) {
       return;
    }
    // payment logic here
}

Das ist falsch, falsch, falsch, aber ich muss es hunderte Male gesehen haben. Die Funktion soll nie mit Null-Zeiger in erster Linie genannt worden, und es ist völlig falsch, sie ruhig zu akzeptieren.

Die hier richtige Ansatz ist umstritten, aber eine Minimallösung ist geräuschvoll zum Scheitern verurteilt, entweder durch eine Assertion oder durch Auslösen einer Ausnahme.

Edit: Ich bin nicht einverstanden mit einigen anderen Antworten und Kommentaren hier - ich glaube nicht, dass alle Funktionen ihre Parameter überprüfen sollten (für viele Funktionen ist dies einfach unmöglich). Stattdessen glaube ich, dass alle Funktionen sollen die Werte dokumentieren, die akzeptabel und Zustand sind, dass andere Werte in undefiniertem Verhalten führen. Dies ist der gewählte Ansatz der erfolgreichsten und am weitesten verbreiteten Bibliotheken jemals geschrieben wird. - Die C- und C ++ Standardbibliotheken

Und lassen Sie jetzt die downvotes beginnen ...

Wenn Sie gerade arbeiten öffentlichen APIs einer Komponente dann seinen Wert eine gute Menge von Parametervalidierung zu tun. Dies führte mich eine Gewohnheit haben Validierung überall zu tun. Das ist ein Fehler. Alle, der Validierungscode wird nie getestet und möglicherweise macht das System komplizierter, als es sein muss.

Nun ziehe ich durch Unit-Tests zu überprüfen. Die Validierung erfolgt auf jeden Fall für Daten aus anderen Quellen kommen, aber nicht für Anrufe aus dem nicht-externen Entwicklern.

Ich Debug.Assert meine Annahmen immer.

Meine persönliche Ideologie. Die Abwehr eines Programms sollte auf die maximale Naivität / Unkenntnis der potenziellen Nutzerbasis proportional

Als defensive gegen Entwickler API-Code raubend ist nicht so verschieden von defensiv gegen regelmäßige Nutzer.

  • Parameter überprüfen, um sicherzustellen, dass sie innerhalb angemessener Grenzen und der erwarteten Typen
  • Stellen Sie sicher, dass die Anzahl der API-Aufrufe, die in Ihren Nutzungsbedingungen sind gemacht werden könnten. Drosselung gilt für Web-es in der Regel nur Dienste und Kennwortüberprüfung Funktionen im Allgemeinen genannt.

Darüber hinaus ist es nicht viel anders, außer zu tun, stellen Sie sicher, Ihre App erholt sich gut im Falle eines Problems, und dass Sie immer genügend Informationen an die Entwickler geben, damit sie verstehen, was los ist.

Defensive Programmierung ist nur eine Möglichkeit, einen Vertrag von hounouring in einer Design-by-Contract Art der Codierung.

Die beiden anderen sind

  • Gesamt Programmierung und
  • nominal Programmierung.

Natürlich können Sie sollen nicht selbst verteidigen gegen jede verrückte Sache ein Entwickler tun könnte, aber dann sollten Sie in Weicht Kontext angeben, es wird tun, was zur Verwendung von Vorbedingungen zu erwarten ist.

//precondition : par is so and so and so 
function doSth(par) 
{
debug.assert(par is so and so and so )
//dostuf with par 
return result
}

Ich glaube, Sie in der Frage zu bringen, ob Sie Tests und sind zu schaffen. Sie sollten in Ihrem Coding Defensive sein, aber wie durch JaredPar wies darauf hin - ich glaube auch, es hängt von der Sprache Sie verwenden. Wenn es nicht verwalteten Code ist, dann sollten Sie extrem defensiv sein. Wenn es gelungen ist, ich glaube, Sie ein wenig wiggleroom haben.

Wenn Sie Tests, und einige andere Entwickler versuchen, den Code zu dezimieren, werden die Tests fehlschlagen . Aber dann wieder, es hängt von der Testabdeckung auf Ihrem Code (falls vorhanden).

Ich versuche, Code zu schreiben, die mehr als defensive, aber rechts unten feindlich. Wenn etwas schief geht, und ich kann es beheben, werde ich. wenn nicht, werfen oder auf die Ausnahme passieren und es jemand anderem Problem machen. Alles, was mit einem physischen Gerät interagiert - Dateisystem, Datenbankverbindung, Netzwerkverbindung sollte unereliable und anfällig für Fehler in Betracht gezogen werden. diese Fehler zu antizipieren und ihnen ist kritisch

Trapping

Wenn Sie diese Einstellung haben, ist der Schlüssel in Ihrem Ansatz, konsequent zu sein. erwarten Sie Statuscodes zur Hand Rückenprobleme in der Call-Kette comminicate oder gefallen Ihnen Ausnahmen. Mischmodelle werden Sie töten oder zumindest fahren Sie zu trinken. schwer. wenn Sie jemand anderem api verwenden, isolieren dann diese Dinge in Mechanismen, die Trap / Bericht in Bezug auf die Sie verwenden. Verwenden Sie dieses Einwickeln Schnittstellen.

Wenn die Diskussion hier, wie defensiv gegen Zukunft kodieren (möglicherweise böswillige oder inkompetent) Maintainer gibt es eine Grenze, was Sie tun können. Durchsetzung von Verträgen durch die Testabdeckung und reichlichen Gebrauch Ihre Annahmen geltend zu machen ist wahrscheinlich das Beste, was Sie tun können, und es sollte in einer Weise geschehen, die im Idealfall den Code nicht Krempel und die Arbeit schwieriger für die Zukunft nicht böse Maintainer des Code. Behauptet sind leicht zu lesen und zu verstehen, und deutlich zu machen, was die Annahmen eines bestimmten Stück Code ist, so dass sie in der Regel eine gute Idee.

Coding defensiv gegen Benutzeraktionen ist ein anderes Thema ganz, und der Ansatz, den ich zu denken, dass der Benutzer mich zu bekommen, ist out. Jede Eingabe wird so sorgfältig untersucht, wie ich verwalten kann, und ich alle Anstrengungen unternehmen, meinen Code haben fail safe - Versuchen keinen Zustand bestehen bleiben, die nicht streng geprüft wird, zu korrigieren, wo Sie können, Ausfahrt anmutig, wenn Sie nicht können, etc. Wenn Sie denken nur über all die bozo Dinge, die auf Ihrem Code von außen Agenten verübt werden könnten, es Ihnen in der richtigen Einstellung wird.

Coding defensiv gegen einen anderen Code, wie Ihre Plattform oder andere Module, ist genau das gleiche wie Benutzer: sie sind Sie raus. Das Betriebssystem ist immer der Thread zur Unzeit gehen tauschen, Netzwerke werden immer zur falschen Zeit gehen sie weg, und im Allgemeinen, das Böse ist reich an jeder Ecke. Sie brauchen nicht da draußen gegen jedes mögliche Problem zu codieren - die Kosten bei der Wartung nicht die Erhöhung der Sicherheit wert sein könnten - aber es tut nicht weh, sicher nicht darüber nachdenken. Und es schadet in der Regel nicht explizit im Code zu kommentieren, wenn es ein Szenario Sie daran gedacht, aber hinsichtlich als unwichtig aus irgendeinem Grunde.

Systeme haben sollten gut Grenzen entwickelt, bei denen defensive Prüfung passiert. Es sollte eine Entscheidung darüber, wo Benutzereingaben validiert ist (zu welcher Grenze) und wo andere potenzielle defensive Probleme erfordern Überprüfung (zB Dritte Integrationspunkte, öffentlich zugängliche APIs, Regel-Engine-Interaktion, oder verschiedene von verschiedenen Teams von Programmierern codierten Einheiten ). Defensive Prüfung als verletzt DRY in vielen Fällen und kommt noch hinzu, Wartungskosten für sehr wenig benifit.

Davon abgesehen, gibt es bestimmte Punkte, an denen Sie nicht zu paranoid sein können. Potential für Pufferüberlauf, Datenkorruption und ähnliche Fragen sollte sehr rigoros verteidigt werden gegen.

I Szenario vor kurzem hatte, in dem die Benutzereingabedaten durch Fern Fassade Schnittstelle propagiert wurde, dann lokale Fassade Schnittstelle, dann eine andere Klasse, um schließlich zu dem Verfahren, wo es tatsächlich verwendet wurde. Ich war mir selbst eine Frage zu stellen: Wann sollte der Wert validiert werden Ich habe nur Validierungscode in die letzte Klasse, wobei der Wert tatsächlich verwendet wurde. Hinzufügen weitere Validierung Code-Schnipsel in Klassen auf dem Ausbreitungsweg Verlegung wäre zu defensiver Programmierung für mich. Eine Ausnahme könnte die Remote-Fassade, aber ich übersprungen es auch.

Gute Frage, ich habe Flip Flop zwischen Plausibilitätsprüfungen zu tun und tun sie nicht. Es ist ein 50/50

Situation, würde ich wahrscheinlich einen Mittelweg nehmen, wo ich würde nur „Bullet Proof“ alle Routinen, die sind:

(a) Wird aufgerufen, aus mehr als einer Stelle im Projekt

(b) hat eine Logik, die sich wahrscheinlich zu ändern ist

(c) Sie können keine Standardwerte

(d) die Routine kann nicht 'nicht bestanden' wird anmutig

Darknight

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top