Question

Je discutais avec un de mes collègues sur la façon défensive votre code devrait être. Je suis toute la programmation pro défensive, mais vous devez savoir où arrêter. Nous travaillons sur un projet qui sera maintenu par d'autres, mais cela ne signifie pas que nous devons vérifier toutes les choses folles un développeur peut faire. Bien sûr, vous pouvez le faire, mais cela va ajouter un très grand frais généraux à votre code.

Comment savez-vous où tracer la ligne?

Était-ce utile?

La solution

Je ne sais pas qu'il n'y a vraiment aucun moyen de répondre à cette question. Il est juste quelque chose que vous apprenez de l'expérience. Vous avez juste besoin de vous demander comment un problème potentiel commun est susceptible d'être et de faire un jugement. Considérez également que vous n'avez pas nécessairement Vous défensivement au code toujours. Parfois, il est juste acceptable de noter tout problème potentiel dans la documentation de votre code.

En fin de compte, je pense que cela est juste quelque chose qu'une personne doit suivre son intuition. Il n'y a pas de bonne ou mauvaise de le faire.

Autres conseils

Tout utilisateur pénètre directement ou indirectement, vous devriez toujours bon sens vérification. Au-delà, quelques s ici et assert il n'y aura pas de mal, mais vous ne pouvez pas vraiment faire grand-chose sur les programmeurs fous d'édition et de briser votre code, de toute façon -)

J'ai tendance à modifier le montant de la défense que je mets dans mon code basé sur la langue. Aujourd'hui, je travaille principalement en C ++ pour que mes pensées sont à la dérive dans cette direction.

Lorsque vous travaillez en C ++, il ne peut y avoir assez de programmation défensive. Je traite mon code comme si je garde les secrets nucléaires et tout autre programmeur est là pour les obtenir. Affirme, plaids, modèle d'erreur du compilateur temps hacks, la validation de l'argument, l'élimination des pointeurs, dans les revues de code de profondeur et la paranoïa générale sont tous de bonne. C ++ est un langage merveilleux mal que je l'amour et sévèrement méfiance.

Je ne suis pas fan du terme « programmation défensive ». Pour moi, il suggère code comme ceci:

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

Ceci est faux, faux, faux, mais je dois l'avoir vu des centaines de fois. La fonction ne doit jamais avoir été appelé avec des pointeurs nuls en premier lieu, et il est tout à fait tort de les accepter en silence.

L'approche correcte ici est discutable, mais une solution minimale est d'échouer à grand bruit, que ce soit en utilisant un ou assert en lançant une exception.

Modifier Je suis en désaccord avec d'autres réponses et commentaires ici - je ne pense pas que toutes les fonctions doivent vérifier leurs paramètres (pour de nombreuses fonctions cela est tout simplement impossible). Au lieu de cela, je crois que toutes les fonctions devraient documenter les valeurs qui sont acceptables et indiquent que d'autres valeurs se traduira par un comportement non défini. Telle est l'approche adoptée par les bibliothèques les plus cotées et largement utilisées jamais écrit -. C et C de bibliothèques standard

Et maintenant, laissez les downvotes commencent ...

Si vous travaillez sur des API publiques d'un composant alors la peine de faire une bonne quantité de validation des paramètres. Cela m'a amené à avoir une habitude de le faire partout la validation. Voilà une erreur. Tout ce que le code de validation n'est testé et rend potentiellement le système plus complexe qu'il doit être.

Maintenant, je préfère valider par des tests unitaires. La validation se produit certainement pour les données provenant de sources externes, mais pas pour les appels de développeurs non externes.

Je Debug.Assert toujours mes hypothèses.

Mon idéologie personnelle. Le programme d'un défensivité doit être proportionnelle à la naïveté / ignorance maximale de la base d'utilisateurs potentiels

être sur la défensive contre les développeurs consumait votre code API n'est pas différent d'être défensive contre les utilisateurs réguliers.

  • Vérifiez les paramètres pour vous assurer qu'ils sont dans des limites appropriées et des types attendus
  • Vérifiez que le nombre d'appels API qui pourrait être fait sont à vos conditions d'utilisation. En général, appelé étranglant il applique généralement aux services Web et des fonctions de contrôle par mot de passe.

Au-delà il n'y a pas grand-chose à faire à part vous assurer que votre application récupère bien en cas d'un problème et que vous donnez toujours amples informations au développeur afin qu'ils comprennent ce qui se passe.

Programmation défensive est qu'une seule façon d'un contrat Hommage rendu aux conception par contrat manière de coder.

Les deux autres sont

  • programmation totale et
  • programmation nominale.

Bien sûr, vous ne devriez pas vous défendre contre tout fou un développeur pourrait faire, mais vous devez indiquer dans Wich contexte, il fera ce qui est attendu à l'utilisation de conditions préalables.

//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
}

Je pense que vous devez apporter à la question de savoir si vous créez des tests aussi bien. Vous devriez être sur la défensive dans votre codage, mais comme l'a souligné JaredPar - Je crois aussi que cela dépend de la langue que vous utilisez. Si son code non géré, alors vous devriez être extrêmement défensive. Si elle a réussi, je crois que vous avez un peu de wiggleroom.

Si vous avez des tests, et un autre développeur tente de décimer votre code, les tests échoueront . Mais là encore, cela dépend de la couverture de test sur votre code (s'il y en a).

J'essaie d'écrire du code qui est plus défensif, mais vers le bas hostile à droite. Si quelque chose va mal et je peux le réparer, je le ferai. sinon, de lancer ou de transmettre l'exception et le rendre quelqu'un problème elses. Tout ce qui interagit avec un dispositif physique - système de fichiers, connexion de base de données, la connexion réseau doit être considéré comme unereliable et sujettes à l'échec. anticiper ces échecs et les piégeant est critique

Une fois que vous avez cet état d'esprit, la clé est d'être cohérent dans votre approche. attendez-vous à restituer les codes d'état à comminicate problèmes dans la chaîne d'appels ou avez-vous comme des exceptions. modèles mixtes vous tuer ou au moins vous conduire à boire. fortement. si vous utilisez quelqu'un d'autre api, puis isoler ces choses dans des mécanismes qui piège / rapport termes que vous utilisez. utiliser ces interfaces d'emballage.

Si la discussion ici est comment coder défensivement contre l'avenir (peut-être maléfiques ou incompétents) mainteneurs, il y a une limite à ce que vous pouvez faire. L'exécution des contrats par la couverture des tests et de l'utilisation libérale de faire valoir vos hypothèses est probablement le meilleur que vous pouvez faire, et cela devrait se faire d'une manière qui ne idéalement encombre pas le code et rendre le travail plus difficile pour les futurs mainteneurs non mal du code. Affirme sont faciles à lire et à comprendre et à préciser quelles sont les hypothèses d'un morceau de code donné est, ils sont donc généralement une bonne idée.

Coding défensivement contre les actions des utilisateurs est une autre question tout à fait, et l'approche que je l'utilise est de penser que l'utilisateur est hors de me faire. Chaque entrée est examiné aussi soigneusement que je peux gérer, et je fais tous les efforts pour avoir mon code fail safe - essayez de ne pas persister tout Etat qui ne sont pas rigoureusement vérifiés, correct où vous pouvez, si vous sortir élégamment ne peut pas, etc. Si vous venez de penser à toutes les choses bozo qui pourraient être commis sur votre code par des agents extérieurs, il vous est dans la bonne mentalité.

Coding défensivement contre d'autres codes, tels que votre plate-forme ou d'autres modules, est exactement la même chose que les utilisateurs: ils sont là pour vous aider. Le système d'exploitation est toujours va échanger votre fil à un mauvais moment, les réseaux vont toujours aller au mauvais moment, et en général, le mal abonde dans tous les coins. Vous n'avez pas besoin de coder contre tous les problèmes potentiels là-bas - le coût de la maintenance pourrait ne pas être utile de l'augmentation de la sécurité - mais il ne vous fait pas mal de penser. Et il ne fait pas mal d'habitude de commenter explicitement dans le code s'il y a un scénario, vous pensé, mais considèrent comme sans importance pour une raison quelconque.

Les systèmes doivent avoir des limites bien conçu où se passe-t vérification défensive. Il devrait y avoir une décision sur l'endroit où l'entrée d'utilisateur est validé (ce qui limite) et où d'autres problèmes défensifs potentiels exigent la vérification (par exemple, des points d'intégration de tiers, publiquement API disponibles, l'interaction des moteurs de règles ou de différentes unités codées par différentes équipes de programmeurs ). vérification plus défensive que viole SEC dans de nombreux cas, et ajoute que les coûts d'entretien pour très peu benifit.

Cela étant dit, il y a certains points où vous ne pouvez pas être trop paranoïaque. Potentiel de dépassements de mémoire tampon, la corruption des données et des problèmes similaires devraient être très rigoureusement défendue contre.

Je scénario ai récemment, dans lequel les données d'entrée d'utilisateur a été propagée par l'interface de façade à distance, puis l'interface de façade locale, puis une autre classe, pour finalement arriver à la méthode où il a été effectivement utilisé. Je demandais moi-même une question: Quand doit être la valeur validée I ajouté le code de validation seulement à la classe finale, où la valeur a été effectivement utilisé. Ajout d'autres extraits de code de validation en cours de pose sur le chemin de propagation serait une programmation trop défensive pour moi. Une exception pourrait être la façade à distance, mais je sautée aussi.

Bonne question, j'ai floppé entre faire chiquenaude contrôles de santé mentale et ne pas les faire. Son 50/50

situation, je serais probablement prendre un juste milieu où je ne « Bullet Proof » toutes les routines qui sont:

(a) appelé à partir de plus d'un endroit dans le projet

(b) a une logique qui est susceptible de changer

(c) Vous ne pouvez pas utiliser les valeurs par défaut

(d) la routine ne peut pas être 'a échoué' gracieusement

Darknight

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top