Il y a de bonnes choses à dire sur le fait d'avoir un seul point de sortie, tout comme il y a de mauvaises choses à dire sur l'inévitable programmation "en flèche" qui en résulte.
Si j'utilise plusieurs points de sortie lors de la validation des entrées ou de l'allocation des ressources, j'essaie de mettre très visiblement toutes les «sorties d'erreur» en haut de la fonction.
L' article sur la programmation spartiate de "SSDSLPedia" et l' article sur le point de sortie de fonction unique du "Wiki de Portland Pattern Repository" contiennent des arguments perspicaces à ce sujet. Bien sûr, il y a aussi ce post à considérer.
Si vous voulez vraiment un seul point de sortie (dans n'importe quelle langue sans exception) par exemple afin de libérer des ressources en un seul endroit, je trouve que l'application soignée de goto est bonne; voir par exemple cet exemple plutôt artificiel (compressé pour économiser l'écran immobilier):
int f(int y) {
int value = -1;
void *data = NULL;
if (y < 0)
goto clean;
if ((data = malloc(123)) == NULL)
goto clean;
/* More code */
value = 1;
clean:
free(data);
return value;
}
Personnellement, en général, je n'aime pas plus la programmation des flèches que je n'aime plusieurs points de sortie, bien que les deux soient utiles lorsqu'ils sont appliqués correctement. Le mieux, bien sûr, est de structurer votre programme pour ne demander ni l'un ni l'autre. Décomposer votre fonction en plusieurs morceaux aide généralement :)
Bien que ce faisant, je trouve que je me retrouve de toute façon avec plusieurs points de sortie comme dans cet exemple, où une fonction plus grande a été décomposée en plusieurs fonctions plus petites:
int g(int y) {
value = 0;
if ((value = g0(y, value)) == -1)
return -1;
if ((value = g1(y, value)) == -1)
return -1;
return g2(y, value);
}
Selon le projet ou les directives de codage, la plupart du code de la plaque de la chaudière pourrait être remplacé par des macros. En remarque, le décomposer de cette façon rend les fonctions g0, g1, g2 très faciles à tester individuellement.
De toute évidence, dans un langage OO et activé par exception, je n'utiliserais pas des instructions if comme ça (ou pas du tout, si je pouvais m'en tirer avec assez peu d'effort), et le code serait beaucoup plus simple. Et non fléché. Et la plupart des retours non définitifs seraient probablement des exceptions.
En bref;
- Peu de retours valent mieux que de nombreux retours
- Plus d'un retour vaut mieux que d'énormes flèches, et les clauses de garde sont généralement correctes.
- Des exceptions pourraient / devraient probablement remplacer la plupart des «clauses de garde» lorsque cela est possible.