Cette question est probablement une langue-agnostique, mais je me concentrerai sur les langues spécifiées.
Tout en travaillant avec un code hérité, j'ai souvent vu des exemples des fonctions, qui (à mon esprit, évidemment) EM> Faites trop de travail dans eux. Je ne parle pas d'environ 5000 monstres locaux, mais sur les fonctions qui mettent en œuvre des contrôles de préequisie à l'intérieur d'eux. P> voici un petit exemple: em> p> Maintenant, lorsque ce type de fonction est appelé, l'appelant n'a pas à s'inquiéter de toutes ces conditions préalables à remplir et on peut simplement dire: P> if (argument1 != null) throw NullArgumentException;
5 Réponses :
"ou - devrait-il simplement lancer des exceptions par chaque incompatibilité de condition préalable?" P>
oui. p>
Je ne suis pas entièrement d'accord avec ça. Il y a des exceptions remarquables pour cela, par exemple les méthodes Tryparse Code>.
@FemAref: En cas de Tryparse CODE>, "L'entrée est analysée" n'est spécifiquement pas une condition préalable.
Je suis d'accord, bien que je ne vais pas donner mon uppot à une réponse que vous mettez clairement aucun effort b> en écriture. Peut-être que vous pourriez la graisser avec une explication de pourquoi i> Ceci est considéré comme une meilleure pratique (et pourquoi il vaut mieux ne pas forcer l'appelant à vérifier) i>?
@Femaref: Comme son nom l'indique, Tryparse tente de faire quelque chose et vous dit si cela réussit ou non. Cela ne dit pas quelles exceptions les exceptions en interne. Par exemple, essayons int32.tryparse. Cette méthode renvoie une valeur entière signée 32 bits équivalente au nombre transmis comme paramètre, si la conversion a réussi ou zéro si la conversion a échoué. La conversion échoue si le paramètre est NULL, n'est pas du format correct, ni représente un nombre inférieur à la mintaille ou supérieure à la maxvalue. Il s'agit donc d'une méthode «spécialement traitée» et non d'un cas général.
Oui, je l'ai eu, j'ai raté la prééréquité i> dans le texte. Je viens de rentrer de l'écriture de mon texte qui gère le cas général de quand jeter une exception et faisait le commentaire de cette hypothèse.
@ukhardy: En réalité int32.tryparse code>
retourne un booléen :)
Je ne suis pas d'accord avec ça. Si quelque chose est vraiment une condition préalable, il devrait jamais i> violé (si c'est le cas, vous devez corriger le code d'appel). Les exceptions ne sont pas pour des choses qui ne devraient jamais arriver, les affirmations sont. Il peut avoir du sens de jeter une exception au lieu d'affirmer s'il s'agit d'une API publique toutefois.
@Blueraja - Danny Pflughoeft: Oh mon cher! J'ai bien peur que vous ignoriez la première ligne de mon commentaire ...
C'est une question intéressante. Vérifiez le concept de "", vous pouvez trouver cela utile. P>
Vous devez faire des chèques avant d'appeler et de fonctionner et si vous possédez la fonction, vous devez le faire lancer des exceptions si les arguments passés ne sont pas comme prévu. P>
Dans votre code d'appel, ces exceptions doivent être traitées. Des arguments de succès passés doivent être vérifiés avant l'appel. P>
Cela dépend. P>
J'aimerais séparer ma réponse entre le boîtier 1, 3 et 2. P>
cas 1, 3 fort> p>
Si vous pouvez récupérer en toute sécurité d'un problème d'argument, ne jetez pas d'exceptions. Un bon exemple sont les méthodes cas 2 fort> p>
J'utiliserais seulement de cette façon si le code est dans une infrastructure comme l'environnement. Récemment, j'ai commencé à réimplémenter la pile LINQ et vous devez mettre en œuvre quelques interfaces - ces implémentations ne seront jamais utilisées en dehors de mes propres classes et méthodes, afin que vous puissiez faire des hypothèses à l'intérieur d'eux - l'extérieur y accédera toujours via l'interface et ne peut pas les créer seuls. P>
Si vous apportez cette hypothèse pour les méthodes API, votre code lancera toutes sortes d'exceptions sur une mauvaise entrée, et l'utilisateur n'a pas de confidentiel ce qui se passe car il ne connaît pas l'intérieur de votre méthode. p> tryparse code> si l'entrée est formatée à tort, elles renvoient simplement
false code>. Sont un autre exemple (à l'exception) sont toutes des méthodes LINQ - elles lancent si la source
est code> est
null code> ou l'un des
func <> code> sont < Code> null code>. Cependant, s'ils acceptent un
personnalisé
icomparer
EqualityComParrer
comparateur
Chaque bloc de fonction / méthode / code doit avoir un Précontion em> , qui sont les circonstances précises dans lesquelles il est conçu pour fonctionner et un postconditions em>, l'état du monde lorsque la fonction revient. Ceux-ci aident vos collègues à comprendre vos intentions. Par définition, le code n'est pas censé fonctionner si la condition préalable est fausse et est considérée comme une buggy si la postconition est fausse. P> Si vous écrivez ces baisse. Dans votre tête, sur papier dans un document de conception, dans les commentaires ou dans les chèques de code réels, c'est une question de goût. P> Mais un problème pratique, à long terme, la vie est plus facile si vous codez la condition préalable et la post-condition comme des contrôles explicites. Si vous cochut de tels chèques, car le code n'est pas censé fonctionner
Avec une fausse condition préalable, ou est une buggy avec une fausse post-componition, les contrôles avant et post-conditions doivent entraîner une erreur de signaler une erreur d'une manière qui facilite la découverte du point d'échec. Quel code ne doit pas faire est simplement "retour" qui n'a rien fait, comme votre exemple montre, car cela implique qu'il a une manière d'une manière ou d'une autre exécutée correctement.
(Code peut bien sûr être défini em> pour quitter ne rien faire, mais si tel est le cas, les pré-conditions doivent refléter cela.) P> Vous pouvez évidemment écrire ce Vérifie avec une instruction IF (votre exemple se ferme dangereusement): p> mais souvent la présence d'une condition pré ou postale est indiquée dans le code en définissant une fonction spéciale en définissant une fonction spéciale en définissant une fonction spéciale / Macro / Déclaration ... pour la langue appelée Assertion em>, et une telle construction spéciale provoque généralement une avortement de programme et une backtrage lorsque l'affirmation est fausse. P> La manière dont le code aurait dû être écrit est la suivante: p> Les fonctions sophistiquées peuvent être prêtes à indiquer à leurs appelants qu'une condition a échoué. C'est l'objet réel des exceptions. Si des exceptions sont présentes, techniquement, la postcondition devrait dire que quelque chose à l'effet de «la fonction peut quitter une exception sous condition XYZ». P> P>
+1, mais vous voulez probablement ! Code> au lieu de
~ code> dans le dernier
affirmation code> (
~ code> in c ++, c # et Java est l'opérateur binaire non)
@Dave: difficile, difficile, difficile ... Il a dit une langue générique: -} Je l'ai changé pour vous rendre heureux.
Oui mais la question est étiquetée c ++, c # et java: p
Bien que la langue spécifique, je pense msdn.microsoft.com/en-us/devlabs/dd491992 < / a> pourrait être intéressant pour vous.
Un jour, lorsque les IDes sont un peu plus visuels (comme Bulles de code ) , Je pense que ces contrats de conception seront quelque chose que vous pouvez simplement spécifier en double-cliquant sur la méthode et en les entrant dans une zone de texte (ou même mieux, en les choisissant dans un menu déroulant). Non seulement ils n'écluent-ils alors plus le code (comme ils ne devraient vraiment pas), mais aussi la génération de documentation sera automatique!