123 votes

Conception par contrat à l'aide d'assertions ou d'exceptions ?

Lors de la programmation par contrat, une fonction ou une méthode vérifie d'abord si ses conditions préalables sont remplies, avant de commencer à travailler sur ses responsabilités, n'est-ce pas ? Les deux façons les plus courantes de procéder à ces vérifications sont les suivantes assert et par exception .

  1. assert n'échoue qu'en mode débogage. Pour s'en assurer, il est crucial de tester (de manière unitaire) toutes les conditions préalables des contrats séparés pour voir si elles échouent réellement.
  2. échoue en mode débogage et en mode libération. L'avantage est que le comportement testé en mode débogage est identique au comportement en mode release, mais les performances d'exécution s'en ressentent.

Lequel est préférable, selon vous ?

Voir question connexe aquí

195voto

Dima Points 19888

La règle de base est que vous devriez utiliser des assertions lorsque vous essayez de détecter vos propres erreurs, et des exceptions lorsque vous essayez de détecter les erreurs des autres. En d'autres termes, vous devez utiliser des exceptions pour vérifier les conditions préalables des fonctions de l'API publique et chaque fois que vous obtenez des données externes à votre système. Vous devez utiliser des assertions pour les fonctions ou les données internes à votre système.

40voto

coppro Points 10692

Désactiver assert dans les versions release revient à dire "je n'aurai jamais aucun problème dans une version release", ce qui n'est souvent pas le cas. Ainsi, assert ne devrait pas être désactivé dans une version release. Mais vous ne voulez pas non plus que la version release se plante à chaque fois qu'une erreur se produit, n'est-ce pas ?

Il faut donc utiliser les exceptions et les utiliser à bon escient. Utilisez une bonne et solide hiérarchie d'exceptions et assurez-vous que vous attrapez et que vous pouvez mettre un crochet sur le lancement d'une exception dans votre débogueur pour l'attraper, et en mode release vous pouvez compenser l'erreur plutôt qu'un plantage pur et simple. C'est la façon la plus sûre de procéder.

22voto

Ged Byrne Points 481

Le principe que je suis est le suivant : Si une situation peut être évitée de manière réaliste par le codage, alors utilisez une assertion. Sinon, utilisez une exception.

Les assertions permettent de s'assurer que le contrat est respecté. Le contrat doit être équitable, de sorte que le client doit être en mesure de s'assurer qu'il est respecté. Par exemple, vous pouvez indiquer dans un contrat qu'une URL doit être valide parce que les règles relatives à ce qui est ou n'est pas une URL valide sont connues et cohérentes.

Les exceptions concernent des situations qui échappent au contrôle du client et du serveur. Une exception signifie que quelque chose a mal tourné et qu'il n'y a rien qui aurait pu être fait pour l'éviter. Par exemple, la connectivité du réseau échappe au contrôle de l'application et il n'y a donc rien à faire pour éviter une erreur de réseau.

J'aimerais ajouter que la distinction entre assertion et exception n'est pas vraiment la meilleure façon de voir les choses. Ce à quoi il faut vraiment penser, c'est au contrat et à la manière dont il peut être appliqué. Dans mon exemple d'URL ci-dessus, la meilleure chose à faire est d'avoir une classe qui encapsule une URL et qui est soit Null, soit une URL valide. C'est la conversion d'une chaîne de caractères en URL qui permet d'appliquer le contrat, et une exception est levée si elle n'est pas valide. Une méthode avec un paramètre URL est beaucoup plus claire qu'une méthode avec un paramètre String et une assertion qui spécifie une URL.

6voto

DJClayworth Points 11288

Les assertions permettent de détecter une erreur commise par un développeur (pas seulement vous, mais aussi un autre développeur de votre équipe). S'il est raisonnable de penser qu'une erreur de l'utilisateur peut créer cette condition, il faut alors prévoir une exception.

De même, pensez aux conséquences. Une affirmation entraîne généralement l'arrêt de l'application. Si l'on peut raisonnablement s'attendre à ce que la condition puisse être rétablie, il est préférable d'utiliser une exception.

En revanche, si le problème peut être sólo est due à une erreur du programmeur, utilisez alors un assert, car vous voulez le savoir le plus tôt possible. Une exception peut être attrapée et gérée, et vous ne vous en apercevrez jamais. Et oui, vous devriez désactiver les assertions dans le code de sortie parce que là vous voulez que l'application se rétablisse s'il y a la moindre chance qu'elle le fasse. Même si l'état de votre programme est profondément cassé, l'utilisateur pourrait être en mesure de sauver son travail.

5voto

Daniel Daranas Points 15123

Il n'est pas tout à fait vrai que "assert fails only in debug mode".

En Construction de logiciels orientés objet, 2e édition de Bertrand Meyer, l'auteur laisse une porte ouverte à la vérification des préconditions en mode release. Dans ce cas, lorsqu'une assertion échoue, une exception de violation d'assertion est levée ! Dans ce cas, il n'y a pas de récupération de la situation : quelque chose d'utile pourrait être fait cependant, et c'est de générer automatiquement un rapport d'erreur et, dans certains cas, de redémarrer l'application.

La raison en est que les préconditions sont généralement moins coûteuses à tester que les invariants et les postconditions et que, dans certains cas, l'exactitude et la "sécurité" de la version finale sont plus importantes que la rapidité. robustesse (la capacité du programme à se comporter de manière sûre lorsque son comportement n'est pas correct, c'est-à-dire lorsqu'un contrat est rompu).

Faut-il toujours laisser les contrôles de précondition activés ? Cela dépend. C'est à vous de décider. Il n'y a pas de réponse universelle. Si vous créez un logiciel pour une banque, il peut être préférable d'interrompre l'exécution avec un message d'alarme plutôt que de transférer 1 000 000 $ au lieu de 1 000 $. Mais qu'en est-il si vous programmez un jeu ? Peut-être avez-vous besoin de toute la vitesse possible, et si quelqu'un obtient 1000 points au lieu de 10 à cause d'un bogue que les conditions préalables n'ont pas détecté (parce qu'elles ne sont pas activées), pas de chance.

Dans les deux cas, vous devez

T y ,

S W

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X