Je déteste faire référence à un contenu payant, mais cette vidéo montre exactement ce dont je parle. Précisément 12 minutes dans Robert Martin regarde ceci:
Et dit: "Une de mes choses préférées à faire est de se débarrasser des accolades inutiles" en le transformant en ceci:
Il y a longtemps, dans une formation lointaine, on m'avait appris à ne pas faire cela, car il est facile d'introduire un bogue en ajoutant une autre ligne indentée pensant qu'elle est contrôlée par le if
moment où ce n'est pas le cas.
Pour être juste avec Oncle Bob, il refacture une longue méthode Java en minuscules petites fonctions qui, j'en conviens, sont beaucoup plus lisibles. Quand il a fini de le changer, (22.18) cela ressemble à ceci:
Je me demande si cela est censé valider la suppression des accolades. Je connais déjà la meilleure pratique . Oncle Bob peut-il être mis au défi sur ce point? Oncle Bob a-t-il défendu cette idée?
la source
if
bloc ne jamais une ligne, il n'a pas d' importance. Si vous devez ajouter plus de lignes, cela devrait être une autre fonction qui réduit leif
bloc à une ligne (l'appel de fonction). Si vous vous en tenez à cela, les accolades n’ont tout simplement aucune importance .return (page==null) ? "" : includePage(mode,page);
s'il en veut un tant soit peu ... Je pensais que le style sans attelle était cool jusqu'à ce que je commence à développer des applications de manière professionnelle. Diff bruit, bugs de typo possibles, etc. Les accolades, étant là tout le temps, vous font économiser le temps et les frais généraux dont vous auriez besoin pour les introduire plus tard.Réponses:
La lisibilité n'est pas une mince affaire.
Je suis d'un esprit mélangé quand il s'agit de croisillons qui enferment une seule méthode. Personnellement, je les supprime pour des choses comme des déclarations sur une seule ligne, mais le fait de laisser de tels crochets nous a en fait mordu très fort au dernier endroit où j'ai travaillé. Quelqu'un a ajouté une ligne de code à une
if
instruction sans ajouter également les accolades nécessaires et, comme il s'agissait de C, le système s'est écrasé sans prévenir.Je ne mets jamais au défi quiconque est religieux de toujours utiliser des attelles après ce petit fiasco.
Je vois donc l’avantage de la lisibilité, mais je suis tout à fait conscient des problèmes qui peuvent survenir lorsque vous omettez ces accolades.
Je ne prendrais pas la peine d'essayer de trouver une étude ou l'opinion publiée de quelqu'un. Tout le monde en a un (c'est-à-dire une opinion), et comme il s'agit d'un problème stylistique, un avis est à peu près aussi bon qu'un autre. Réfléchissez vous-même au problème, évaluez le pour et le contre et décidez vous-même. Si le magasin pour lequel vous travaillez a une norme de codage qui couvre ce problème, suivez-le.
la source
-Wmisleading-indentation
.Vous pouvez trouver plusieurs promotions publiées ou des rejets de styles sans attelle ici ou ici ou partout où des hangars à vélos sont peints.
En vous éloignant des abris à vélo, vous souvenez-vous de l'excellent bogue SSL OS X / iOS de 2014?
Oui, "causé" par des blocs sans attache https://www.imperialviolet.org/2014/02/22/applebug.html
Les préférences peuvent dépendre du style d'accolade. Si je devais écrire
Je pourrais être enclin à économiser de l'espace aussi. Mais
utilise uniquement une ligne "extra".
Je sais que vous n'avez pas demandé, mais si je travaille seul, je suis un hérétique. Si je retire les bretelles, je préfère
Il n'a pas le même problème visuel que le bogue de style SSL iOS, mais enregistre encore plus de lignes "inutiles" qu'Oncle Bob;) Lit bien si vous y êtes habitué et a une utilisation courante dans Ruby (
includePage(mode, suiteSetup) unless suiteSetup.nil?
). Oh bien, sachez qu'il y a beaucoup d'opinions.la source
} else[if(...)] {
, cela n’ajoute pas de lignes supplémentaires, ce qui fait qu’il n’a qu’une seule ligne supplémentaire.Oncle Bob dispose de nombreuses couches de défense contre une telle erreur qui n’était pas aussi courante quand "toujours utiliser des accolades" était la sagesse qui prévalait:
Je pense que si quelqu'un publiait un défi contre Oncle Bob, il aurait une assez bonne réfutation avec les points ci-dessus. C'est l'une des erreurs les plus faciles à détecter tôt.
la source
while(true);{break;}
. S'il existe vraiment un contexte valable pour cela, il me faudra un certain temps pour le surmonter.includePage()
macro n’est pas mal écrite avec plus d’une déclaration?Pour la plupart, il s'agit d'une préférence personnelle, mais il y a certaines choses à considérer.
Bugs possibles
Bien que l' on peut soutenir que les bugs causés par l' oubli d'accolades add-in sont rares, de ce que j'ai vu que ils ne se produisent de temps en temps (ne pas oublier le fameux goto IOS échec bug). Donc, je pense que cela devrait être un facteur lors de l'examen de votre style de code (certains outils vous avertissent de l' indentation trompeuse , donc cela dépend aussi de votre chaîne d'outils) .
Code valide (qui se lit comme si cela pouvait être un bogue)
Même en supposant que votre projet ne souffre pas de tels bogues, lors de la lecture du code, vous pouvez voir des blocs de code qui pourraient ressembler à des bogues - mais ne le sont pas, prenant en compte certains de vos cycles mentaux.
Nous commençons par:
Un développeur ajoute un commentaire utile.
Plus tard, un développeur l'étend.
Ou ajoute un bloc imbriqué:
Ou utilise une macro:
"... Étant donné que les macros peuvent définir plusieurs lignes de code, la macro utilise-
do {...} while (0)
t-elle plusieurs lignes? Ce devrait être parce que c'est dans notre guide de style, mais je ferais mieux de vérifier au cas où!!"Les exemples ci-dessus sont tous du code valide. Cependant, plus le contenu du bloc de code est important, plus vous devez lire pour vous assurer qu'il n'y a pas d'erreur.
Peut-être que votre style de code définit que les blocs multilignes nécessitent une accolade (peu importe le type, même s'ils ne sont pas du code) , mais j'ai déjà vu ce genre de commentaires être ajoutés au code de production. Lorsque vous le lisez, il y a un petit doute sur le fait que celui qui a modifié ces lignes en dernier ait oublié d'ajouter une accolade. Parfois, je ressens le besoin de vérifier si tout se passe bien (surtout lorsque vous recherchez un bogue dans cette partie du code) .
Diff bruit
Une raison pratique d'utiliser des accolades pour des lignes simples est la réduction du bruit diff .
C'est-à-dire changer:
À:
... provoque l'affichage de la ligne conditionnelle dans un diff comme étant modifiée, ce qui ajoute une surcharge légère mais inutile.
Cela dit, tous les outils ne prennent pas en charge la différenciation basée sur les mots: diff (svn, git, hg, etc.) montrera que si la ligne entière était modifiée, même avec des outils sophistiqués, vous devrez parfois parcourir rapidement une ligne simple. basé sur diff pour voir ce qui a changé.
git blame
) indiquent que la ligne a été modifiée, ce qui rend le suivi de l'origine d'une ligne plus complexe pour trouver le changement réel .Celles-ci sont toutes deux petites et dépendent du temps que vous consacrez à la révision du code ou au suivi du code pour valider les lignes de code modifiées.
Un inconvénient plus tangible d'avoir des lignes supplémentaires change dans un diff, leur plus grande probabilité que des modifications dans le code provoquent des conflits qui se fusionnent et qui doivent être résolus manuellement .
Il y a une exception à cela, pour les bases de code qui ont
{
sur leur propre ligne - ce n'est pas un problème.L' argument de bruit diff ne tient pas si vous écrivez dans ce style:
Cependant, ce n'est pas une convention si commune, donc il faut principalement ajouter la réponse pour la complétude (ne suggérant pas aux projets d'utiliser ce style) .
la source
{
style -on-its-own-line. Je déteste vraiment ce style et n'aime pas travailler sur des projets où ce style est requis. Peut-être avec cela à l'esprit, je trouverai un peu moins frustrant d'avoir à coder de cette façon. La densité de code est importante. Si vous pouvez voir toutes les fonctions à la fois sur votre moniteur, vous pouvez plus facilement tout comprendre. J'aime laisser des lignes vides entre des blocs de code distincts à l'intérieur d'une fonction pour des raisons de lisibilité (pour regrouper les déclarations associées), et être obligé de perdre de l'espace ailleurs, affaiblit les coupures prévues.{
style en ligne, ne l’a inclus que pour l’intégralité des réponses. En ce qui concerne les macros de confiance à utiliserdo{}while(0)
, je trouve que le problème est que vous pouvez y faire confiance presque tout le temps. Le problème, c’est que des accidents surviennent, que des erreurs peuvent se glisser lors de la révision du code ... et que des bugs peuvent être introduits, qui ne seraient pas autrement.Il y a des années, j'ai été amené à déboguer du code C. Le bogue était difficile à trouver, mais il a finalement abouti à une déclaration comme celle-ci:
Et il s’est avéré que la personne qui l’avait écrite s’était définie
foo
comme une macro. Une macro avec deux lignes de code. Et bien sûr, seule la première de ces deux lignes était soumise à laif
. (Donc, la deuxième ligne a été exécutée sans condition.)Cela peut être absolument unique à C et à son pré-processeur - qui effectue les substitutions avant la compilation - mais je ne l’ai jamais oublié. Ce genre de chose vous marque, et pourquoi ne pas jouer prudemment - surtout si vous utilisez une variété de langages et d'outils et que vous ne pouvez pas être sûr que de telles manigances ne sont pas possibles ailleurs?
Maintenant, j'indente et utilise les accolades différemment des autres, apparemment. Pour une seule ligne
if
, je ferais:il ne faut donc aucune ligne supplémentaire pour inclure les accolades.
la source
do { ... } while(0)
boucle. Cela garantira non seulement qu'il sera toujours traité correctement en englobant desif()
instructions, mais également que le point-virgule à la fin de l'instruction sera avalé correctement. Quiconque ne connaît pas de telles règles simples ne doit tout simplement pas écrire de macros de préprocesseur. Défendre sur le site de l'appelant n'est pas le bon endroit pour se défendre."Oncle Bob" est autorisé à avoir son opinion, vous êtes autorisé à avoir votre opinion. Pas besoin de le défier.
Si vous voulez faire appel à l'autorité, prenez Chris Lattner. Dans Swift, si les instructions ont perdu leurs parenthèses, mais toujours avec des accolades. Aucune discussion, cela fait partie du langage. Donc, si "Uncle Bob" commence à supprimer les accolades, le code cesse de compiler.
Passer par le code de quelqu'un d'autre et "se débarrasser des accolades inutiles" est une mauvaise habitude. Ne provoque un travail supplémentaire que lorsque le code doit être révisé et que des conflits sont créés inutilement. Peut-être que "Uncle Bob" est un si bon programmeur qu'il n'a pas besoin de révision de code? J'ai perdu une semaine de ma vie parce qu'un des meilleurs programmeurs a changé "if (p! = NULL)" en "if (! P)" sans vérification du code, caché au pire endroit possible.
C'est surtout un débat de style inoffensif. Les accolades ont l’avantage de pouvoir insérer une autre ligne de code sans ajouter d’accolades. Comme une déclaration de journalisation ou un commentaire (s'il est suivi d'un commentaire suivi d'une déclaration, c'est horrible). instruction sur la même ligne que si a l'inconvénient pratique que vous avez des problèmes avec de nombreux débogueurs. Mais fais ce que tu préfères.
la source
Mes raisons pour ne pas enlever les accolades sont les suivantes:
réduire la fatigue de décision. Si vous utilisez toujours des accolades, vous n'avez jamais à décider si vous allez en avoir besoin ou non.
réduire la traînée de développement: même si vous essayez d' extraire éventuellement toutes les lignes de la logique en méthodes, vous devez convertir un sans bracelet si en une doublée si l'ajout de logique est un peu désagréable en matière de développement. Il faut donc supprimer les accolades et les rajouter lorsque vous avez besoin de plus de code. Minuscule, mais ennuyeux.
la source
Un jeune collègue a déclaré que les accolades que nous considérons comme redondantes et superflues lui sont en fait utiles. Je ne me souviens pas exactement pourquoi, mais si cela lui permet d'écrire un meilleur code plus rapidement, c'est la seule raison de le conserver.
FWIW, nous avons convenu d'un compromis qui les mettre sur une ligne ne fait pas de telles conditions court un lecture / distrayant pour moi. Par exemple
Je souligne également que ces conditions préalables d'introduction sont souvent des déclarations de flux de contrôle pour le corps (par exemple, un
return
), de sorte que la crainte d'ajouter une deuxième déclaration censée être dans les mêmes conditions et d'oubli pour écrire des accolades est sans objet. Une seconde déclaration sous la condition serait de toute façon un code mort et n'aurait aucun sens.Je soupçonne que le problème de la maîtrise de la lecture est dû au fait que l'analyseur cérébral de la personne est câblé pour que les accolades fassent partie intégrante de l'énoncé conditionnel. Ce n'est pas une représentation précise de la grammaire du C ++, mais pourrait être un effet secondaire de l'apprentissage de certaines autres langues en premier, où c'est le cas.
la source
Après avoir visionné cette vidéo tout à l’heure, j’ai remarqué que l’élimination des accolades permettait de voir plus facilement où le code devait encore être refondu. Si vous avez besoin d'accolades, votre code peut probablement être un peu plus propre.
Cela dit, lorsque vous faites partie d’une équipe, l’élimination des accolades entraînera probablement un comportement inattendu un jour. Je leur dis de les garder et vous éviterez beaucoup de maux de tête en cas de problème.
la source
Si votre code est bien testé , ce type de "bogue" exploserait au visage.
Nettoyer le code en évitant les crochets inutiles et laids est une pratique que je suis.
la source