Cette notion de SESE ( Single Entry, Single Exit ) provient de langages à gestion de ressources explicite , comme le C et l’assemblage. En C, un code comme celui-ci perdra des ressources:
void f()
{
resource res = acquire_resource(); // think malloc()
if( f1(res) )
return; // leaks res
f2(res);
release_resource(res); // think free()
}
Dans de telles langues, vous avez essentiellement trois options:
Répliquez le code de nettoyage.
Pouah. La redondance est toujours mauvaise.
Utilisez a goto
pour passer au code de nettoyage.
Cela nécessite que le code de nettoyage soit la dernière chose dans la fonction. (Et c’est pourquoi certains prétendent que cela goto
a sa place. Et c’est vrai - en C.)
Introduisez une variable locale et manipulez le flux de contrôle.
L'inconvénient est que le flux de commande manipulé par la syntaxe (pensez break
, return
, if
, while
) est beaucoup plus facile à suivre que le flux de contrôle manipulé par l'état des variables (parce que ces variables ont pas d' état quand vous regardez l'algorithme).
En assembleur, c'est encore plus étrange, car vous pouvez accéder à n'importe quelle adresse d'une fonction lorsque vous appelez cette fonction, ce qui signifie que vous disposez d'un nombre presque illimité de points d'entrée pour n'importe quelle fonction. (Parfois, cela est utile. De tels thunks sont une technique courante permettant aux compilateurs d'implémenter l' this
ajustement de pointeur nécessaire pour appeler des virtual
fonctions dans des scénarios d'héritage multiples en C ++.)
Lorsque vous devez gérer les ressources manuellement, exploiter les options permettant d'entrer ou de quitter une fonction n'importe où conduit à un code plus complexe, et donc à des bogues. Par conséquent, une école de pensée est apparue qui a propagé SESE, afin d'obtenir un code plus propre et moins de bugs.
Cependant, lorsqu'une langue comporte des exceptions, (presque) n'importe quelle fonction peut être abandonnée prématurément à (presque) n'importe quel moment. Vous devez donc prévoir le retour prématuré de toute façon. (Je pense que finally
c'est principalement utilisé pour cela en Java et using
(lors de l'implémentation IDisposable
, finally
sinon) en C #; C ++ utilise à la place RAII .) Une fois que vous avez effectué cela, vous ne pouvez pas vous empêcher de nettoyer après vous-même en raison d'une return
déclaration précoce . l'argument le plus fort en faveur de SESE a disparu.
Cela laisse la lisibilité. Bien sûr, une fonction 200 LoC avec une demi-douzaine d' return
instructions saupoudrées au hasard n'est pas un bon style de programmation et ne permet pas un code lisible. Mais une telle fonction ne serait pas facile à comprendre sans ces retours prématurés.
Dans les langues où les ressources ne sont pas ou ne devraient pas être gérées manuellement, l'adhésion à l'ancienne convention SESE n'a que peu, voire aucune valeur. OTOH, comme je l'ai déjà expliqué, SESE rend souvent le code plus complexe . C'est un dinosaure qui (à l'exception du C) ne correspond pas à la plupart des langues actuelles. Au lieu d’aider le caractère compréhensible du code, il l’entrave.
Pourquoi les programmeurs Java s'en tiennent-ils à cela? Je ne sais pas, mais de mon point de vue (extérieur), Java a pris un grand nombre de conventions de C (où elles ont un sens) et les a appliquées à son monde OO (où elles sont inutiles ou carrément mauvaises), où il s’en tient maintenant. eux, peu importe les coûts. (Comme la convention pour définir toutes vos variables au début de la portée.)
Les programmeurs s'en tiennent à toutes sortes de notations étranges pour des raisons irrationnelles. (Les énoncés structurels profondément imbriqués - les "pointes de flèches" - étaient, dans des langages comme Pascal, considérés jadis comme un code magnifique.) L'application d'un raisonnement purement logique à cet objectif ne semble pas convaincre la majorité d'entre eux de s'écarter de leurs méthodes habituelles. La meilleure façon de changer de telles habitudes est probablement de leur apprendre très tôt à faire ce qui est le mieux, et non ce qui est conventionnel. En tant que professeur de programmation, vous l’avez entre les mains.:)