2008-11-24 7 views

Répondre

46

j'aime éliminer les cas d'erreur premier - et le retour de la fonction tôt pour que le « chemin heureux » reste un emboîtés, par exemple

if (some error condition) 
{ 
    //handle it 
    return; 
} 
//implicit else for happy path 
... 

s'il est facile d'identifier les conditions menant au chemin heureux, puis par tous les moyens mis cette clause premier (merci Marcin!)

+2

Bonne réponse. Ce modèle est communément appelé "clause de garde". –

+0

Désolé, je ne peux pas être d'accord avec ça. S'il vous plaît voir ma réponse ci-dessous. – Marcin

+0

@DLarsen: réponse éditée pour refléter le conseil de Marcin également –

4

si ses 1 ou 2 lignes et un retour rapide, je 'd le mettre au sommet - surtout si c'est au début de la fonction. cela ressemble presque à un contrat. sinon, je vais avec la règle "conditions positives avant négatives".

0

Cela dépend de ce qui vous est le plus clair. Je veux dire, ce qui a plus de sens, c'est que noProblems a une valeur vraie ou qu'elle a une fausse valeur.

Par exemple pour isDeviceEnabled() je vérifierais toujours un résultat vrai car "Activé" a implicitement une valeur positive. Pour une valeur négative implicite nous pourrions vérifier par exemple pour "isMemoryAvailable()", peut-être parce que vous devez vérifier seulement s'il n'y a plus de place pour de nouveaux objets/tableaux ou d'autres données.

0

C'est une décision très individuelle, mais j'ai tendance à mettre mes conditions d'erreur en premier, sous prétexte de regrouper comme du code. C'est-à-dire que si je fais quelque chose, et que cela échoue, la vérification de cet échec fait en réalité partie de quelque chose; si je mets la vérification de l'échec et de l'action sur la base de cela au début de mon code, j'ai regroupé mon action et la réponse complexe à cette action ensemble (en supposant qu'un résultat de défaillance est en fait un cas de retour plus complexe que un succès).

0

La première me semble légèrement préférable en ce qu'elle évite un double négatif au conditionnel.

Autre que cela, vous avez construit des choses afin que vous ne pouvez pas vraiment

// do stuff 

après avoir

// deal with problem 

donc au-delà semble aussi bon que l'autre.

0

Comme avec try/catch Je fais le flux normal, puis je gère les conditions d'exception.

Cela ne signifie pas que la vérification/le nettoyage des erreurs ne se produit pas en premier, mais c'est si je ne fais pas confiance à ce qui m'a été transmis.

par exemple,

if (foo is null) then 
    // bail 
end if 

if (bar == foo) then 
    // foo hasn't been changed... print the regular report 
else 
    // foo has changed, run the reconciliation report instead. 
end if 

J'aime l'histoire heureux de couler comme une ligne droite, et l'histoire malheureuse de spin off sur son éperon.

7

Peut-être que cela dépend des conventions de langage, ou d'autres facteurs, mais je pense que le cas nominal devrait être au sommet, et les branches devraient contenir les conditions exceptionnelles. Cela rend le code beaucoup plus facile à lire.Ceci est particulièrement vrai quand il y a beaucoup de conditions exceptionnelles, et dans la plupart des cas, il y en a. Vous serez en mesure de supposer facilement que l'auteur s'attend à ce que ce chemin spécifique soit pris la plupart du temps, et de comprendre le code plus facilement de cette façon.

De « code complet, 2ème édition » l'article 15.1:

En mettant les cas les plus communs d'abord, vous réduisez la quantité de quelqu'un de code de gestion des exceptions cas doit lire pour trouver les cas habituels. Vous améliorez l'efficacité car vous minimisez le nombre de tests effectués par le code pour trouver les cas les plus courants.

+6

Vous pouvez également lire la section 17.1, qui dit: "Utiliser des clauses de garde (retours anticipés ou sorties) pour simplifier le traitement des erreurs complexes" –

+0

je serais d'accord dans le cas où il est facile d'identifier les conditions qui mènent à la voie heureuse, éditera ma réponse pour refléter votre sagesse supplémentaire –

0

Pourquoi ne pas créer un point de sortie de la fonction et le nettoyage approprié il faire au lieu d'avoir des retours multiples ...

 

DWORD bRetVal= TRUE; 
if(foo is null) 
{ 
    bRetVal = FALSE; 
    goto Error; 
} 
else 
{ 
// do something 
} 

Exit: 
return bRetVal; 

 
Questions connexes