À partir de certains projets open source, j'ai rassemblé le style de codage suivant
void someFunction(bool forget);
void ourFunction() {
someFunction(false /* forget */);
}
J'ai toujours un doute sur ce que cela false
signifie ici. Cela signifie-t-il "oublier", ou "oublier" fait-il référence à son paramètre correspondant (comme dans le cas ci-dessus), et "faux" est-il censé le nier?
Quel style est utilisé le plus souvent et quel est le meilleur moyen (ou certains des meilleurs moyens) pour éviter l'ambiguïté?
coding-style
comments
boolean
Johannes Schaub - litb
la source
la source
someFunction(forget: true);
true
àfalse
et mettre à jour le commentaire. Si vous ne pouvez pas modifier l'API, alors la meilleure façon de commenter cela estsomeFunction( false /* true=forget, false=remember */)
sortAscending
etsortDescending
, ou similaire). Maintenant, à l' intérieur , ils peuvent tous deux appeler la même méthode privée, qui pourrait avoir ce type de paramètre. En fait, si la langue le supportait, ce que je passerais probablement serait une fonction lambda qui contiendrait le sens du tri ...Réponses:
Dans l'exemple de code que vous avez publié, il ressemble à
forget
un argument indicateur. (Je ne peux pas en être certain car la fonction est purement hypothétique.)Les arguments de drapeau sont une odeur de code. Ils indiquent qu'une fonction fait plus d'une chose et qu'une bonne fonction ne devrait faire qu'une seule chose.
Pour éviter l'argument indicateur, divisez la fonction en deux fonctions qui expliquent la différence dans le nom de la fonction.
Argument indicateur
Aucun argument de drapeau
edit: Idéalement, vous n'avez pas du tout besoin de rester autour d'une fonction avec le paramètre flag. Il existe des cas dans le sens de ce que Fowler appelle une implémentation enchevêtrée où la séparation complète des fonctions crée du code dupliqué. Cependant, plus la complexité cyclomatique de la fonction paramétrée est élevée, plus l'argument pour s'en débarrasser est fort.
Ce n'est qu'une intuition, mais un paramètre nommé
forget
sonne comme l'envie de fonctionnalités. Pourquoi un appelant dirait-il à un autre objet d'oublier quelque chose? Il peut y avoir un problème de conception plus important.la source
serveTraditionalIceCream
etserveLowFatIceCream
ressembler? J'ai une énumération avec 14 types de crème glacée.Dans les mots du profane:
false
est un littéral.false
someFunction
de ne pas oubliersomeFunction
que le paramètre oublier estfalse
someFunction
de te souvenirÀ mon avis, il serait préférable que la fonction soit comme ceci:
le vous pouvez l'appeler
ou conservez l'ancien nom mais changez votre fonction wrapper en
ÉDITER:
Comme l'a indiqué @Vorac, efforcez-vous toujours d'utiliser des mots positifs. La double négation prête à confusion.
la source
remember
, à moins que le nom de la fonction ne fasse le sens deremember
très évident.rememberToCleanUp* or *persist
ou quelque chose.Le paramètre peut être bien nommé; c'est difficile à dire sans connaître le nom de la fonction. Je suppose que le commentaire a été écrit par l'auteur original de la fonction, et ce fut un rappel de ce qui passe
false
dans lessomeFunction
moyens, mais pour ceux qui viennent le long après, il est un peu difficile de prime abord.L'utilisation d'un nom de variable positif (suggéré dans Code Complete ) peut être le changement le plus simple qui rendrait cet extrait plus facile à lire, par exemple
ourFunction
devient alors :Cependant, l'utilisation d'une énumération rend l'appel de fonction encore plus facile à comprendre, au détriment de certains codes de support:
Si vous ne pouvez pas modifier la signature de
someFunction
pour une raison quelconque, l'utilisation d'une variable temporaire facilite également la lecture du code, un peu comme la simplification des conditions en introduisant une variable pour aucune autre raison que pour rendre le code plus facile à analyser par les humains .la source
remember
sur vrai signifie oublier (dans votre exemple desomeFunction(true /* forget */);
)?enum
de loin la meilleure solution. Ce n'est pas parce qu'un type peut être représenté commebool
- c'est-à-dire qu'il est isomorphe - qu'il doit être représenté comme tel. Le même argument s'applique àstring
et mêmeint
.Renommez la variable pour qu'une valeur booléenne ait un sens.
C'est un million de fois mieux que d'ajouter un commentaire pour expliquer les arguments d'une fonction car le nom est ambigu.
la source
Créez un booléen local avec un nom plus descriptif et affectez-lui la valeur. De cette façon, le sens sera plus clair.
Si vous ne pouvez pas renommer la variable, alors le commentaire devrait être un peu plus expressif:
la source
/* forget */
commentaire est là pour résoudre, à savoir que sans la déclaration de fonction juste devant vous, il peut être difficile de se rappeler ce qui est régléfalse
. (C'est pourquoi je pense que les conseils de @ Esailija pour ajouter une énumération sont meilleurs, et pourquoi j'aime les langages qui autorisent les paramètres nommés.)Il y a un bon article qui mentionne cette situation exacte car elle se réfère aux API Qt-Style. Là, ça s'appelle le piège des paramètres booléens et il vaut la peine d'être lu.
L'essentiel est:
la source
Ceci est un commentaire bizarre.
Du point de vue du compilateur,
someFunction(false /* forget */);
est en faitsomeFunction(false);
(le commentaire est supprimé). Donc, tout ce que cette ligne fait est d'appelersomeFunction
avec le premier (et le seul) argument défini surfalse
./* forget */
est juste le nom du paramètre. Ce n'est probablement rien de plus qu'un rappel rapide (et sale), qui n'a pas vraiment besoin d'être là. Utilisez simplement un nom de paramètre moins ambigu et vous n'aurez pas du tout besoin du commentaire.la source
Un des conseils du code Clean est de minimiser le nombre de commentaires inutiles 1 (car ils ont tendance à pourrir) et de nommer correctement les fonctions et les méthodes.
Après cela, je voudrais simplement supprimer le commentaire. Après tout, les IDE modernes (comme eclipse) font apparaître une boîte avec du code lorsque vous placez une souris sur la fonction. Voir le code devrait lever toute ambiguïté.
1 Commenter du code complexe est correct.
la source
Pour comprendre l'évidence, des commentaires peuvent mentir. Il est donc toujours préférable de rendre votre code auto-documenté sans recourir à des commentaires pour l'expliquer, car une personne (peut-être vous) changera
true
pourfalse
et mettre à jour le commentaire.Si vous ne pouvez pas changer l'API, je recourt à 2 options
la source
J'aime la réponse pour rendre le commentaire toujours vrai , mais bien que je pense qu'il manque le problème fondamental avec ce code - il est appelé avec un littéral.
Vous devez éviter d'utiliser des littéraux lors de l'appel de méthodes. Variables locales, paramètres facultatifs, paramètres nommés, énumérations - la meilleure façon de les éviter dépendra de la langue et de ce qui est disponible, mais essayez de les éviter. Les littéraux ont des valeurs, mais ils n'ont pas de sens.
la source
En C #, j'ai utilisé des paramètres nommés pour rendre cela plus clair
Ou
enum
:Ou surcharges:
Ou polymorphisme »:
la source
La dénomination doit toujours résoudre l'ambiguïté des booléens. Je nomme toujours quelque chose de booléen comme 'isThis' ou 'shouldDoThat', par exemple:
etc. Mais lorsque vous référencez le code de quelqu'un d'autre, il est préférable de laisser un commentaire lors du passage de valeurs.
la source