6
votes

Y a-t-il une raison d'éviter le motif sentinel en Java?

J'ai entendu des gens conseillent qu'il faut toujours utiliser Modèle Itérateur pour contrôler les boucles Plutôt que de jeter une exception (ce qui est fonctionné dans Itérateurs Python ) ou en utilisant le modèle Sentinel , dans laquelle une valeur spéciale et sentinelle (souvent null < / code>) est renvoyé pour indiquer la fin de l'itération.

Les meilleures pratiques conseillent-elles contre le motif sentinelle? Si oui, pourquoi? (autre qu'il ne fonctionne pas avec la syntaxe foreach dans JAVA 1.5).

EDIT: Exemple de code 1 - motif Sentinel xxx

code de code 2 - motif d'itérateur xxx


3 commentaires

Vous voudrez peut-être montrer un exemple de chacun des trois modèles de boucle que vous posez.


N'incluait pas la manière Python, élever des exceptions pour le flux de contrôle n'est pas quelque chose que je suggère sérieusement.


+1 Juste pour les E / S pour la boucle - Je n'ai jamais vu cela fait de cette façon.


7 Réponses :


15
votes

Le problème avec le modèle Sentinel est qu'il exclut explicitement la valeur Sentinel de l'ensemble des valeurs qui sont des éléments valides. C'est-à-dire que si vous avez une liste d'objets qui peuvent valablement contenir NULL en tant qu'élément, à l'aide de NULL comme une valeur sentinelle est un échec.


0 commentaires

9
votes

Les exceptions ne doivent être utilisées que dans des situations "exceptionnelles". La conclusion ou la rupture d'une boucle est un flux de programme normal, pas une situation exceptionnelle.

En outre, lorsque vous travaillez en Java (ou dans une langue de cette affaire), vous souhaitez utiliser des modèles et des conventions communs et bien connus dans la communauté car d'autres programmeurs Java peuvent avoir besoin de maintenir votre code. S'ils le font, ils s'attendront probablement à voir des itérateurs, pas du motif sentinel.


1 commentaires

Je suis d'accord avec ce principe et je recommande de suivre. Le Secret Secret est que la version d'exception est incroyablement rapide, ESP si vous avez utilisé une exception mises en cache Singleton. Mais je ne ferais pas cela à moins d'avoir besoin d'une vitesse folle et je pourrais prouver que c'était plus rapide. Je le mentionne ici simplement parce que c'est intéressant.



0
votes

Je ne vois pas comment le motif sentinel est suffisamment différent pour être son propre modèle. Ma seule pensée est qu'il serait utile de déterminer une valeur d'arrêt des données en continu. Cependant, l'interacateur s'occupe de cela avec la méthode "Hasmore" requise.


0 commentaires

2
votes

Le motif Sentinel est utilisé dans le JDK pour les flux de lecture, de sorte qu'il n'est pas inutile, mais il est gênant de faire une boucle de. Toutes les solutions ont des négatifs qu'un itérateur ne le fait pas. Votre solution nécessite un appel répétitif à lire (c'est-à-dire une duplication de code). Une boucle tandis que la boucle force la variable à déclarer en dehors du cadre de la boucle. D'autres alternatives seraient surprenantes et difficiles à suivre.

Donc, à la fin, l'itérateur est en quelque sorte la valeur par défaut qui ne devrait être déviée que pour une raison.


0 commentaires

4
votes

Je pense qu'ils sont tous les deux, mais l'itérateur est plus idiomatique en Java (en particulier si vous avez en réalité une iérienne que vous pouvez utiliser la boucle pour chacune à la place).

Le seul endroit où vous voyez la version sentinelle beaucoup en Java est exactement le cas que vous avez écrit en code d'E / S.


1 commentaires

+1 Pour souligner qu'il n'y a pas de règle difficile et rapide qui couvre tous les cas, chaque modèle a ses propres avantages et inconvénients.



3
votes

Le mantra est "Dites ce que vous faites, et faites ce que vous dites."

Si vous testez la valeur renvoyée pour être une valeur spéciale, qui ne dit rien pourquoi vous testez cela. Dans votre exemple: xxx

est-ce que cela dit "si la valeur renvoyée devient -1, nous pouvons sauter le reste" ou "si la valeur retournée est de -1, Une erreur s'est produite "ou" si la valeur renvoyée est de -1, la fin est atteinte "? En revanche, hasnext est totalement sans ambiguïté.

Au fait, j'aimerais réellement le foreach et mappe construit d'autres langues fournir (ou permettre d'écrire) mieux que la boucle explicite.


0 commentaires

0
votes

"Les exceptions ne doivent être utilisées que dans des situations" exceptionnelles ". La conclusion ou la rupture d'une boucle est un flux de programme normal, pas une situation exceptionnelle."

Si un fichier lu succède à un million de fois et seulement la dernière fois qu'elle dit "Je ne trouve plus d'enregistrements", vous n'appelez pas cela «exceptionnel»?

Je ne vois pas le problème à l'aide, disons, des idées de contrôle du flux de contrôle (si le système est Assez sain d'esprit pour les élever, au lieu de retourner cet entier très stupide -1 en disant que "-1 octets étaient lus"). Vous me dites si ce qui suit est illisible / homologuifique: xxx


2 commentaires

Si vous n'aimez pas la sentinelle, une méthode booléenne est bien meilleure que de simplement attraper une exception de temps (vrai).


Eh bien, j'espère atteindre la condition de sortie Je ne trouve plus d'enregistrement n'est pas exceptionnel. Lorsque cela est exceptionnel, votre programme est buggy. Vous devez séparer les et et des cas exceptionnels . Peu importe combien de lectures de fichiers faites ou autre chose - cette affaire n'est pas exceptionnelle.