Pourquoi est-il considéré comme une mauvaise pratique d'omettre les accolades? [fermé]


180

Pourquoi tout le monde me dit-il qu'écrire du code comme celui-ci est une mauvaise pratique?

if (foo)
    Bar();

//or

for(int i = 0 i < count; i++)
    Bar(i);

Mon plus grand argument pour omettre les accolades est qu'il peut parfois y avoir deux fois plus de lignes avec eux. Par exemple, voici du code pour peindre un effet d'éclat pour une étiquette en C #.

using (Brush br = new SolidBrush(Color.FromArgb(15, GlowColor)))
{
    for (int x = 0; x <= GlowAmount; x++)
    {
        for (int y = 0; y <= GlowAmount; y++)
        {
            g.DrawString(Text, this.Font, br, new Point(IconOffset + x, y));
        }
     }
 }
 //versus
using (Brush br = new SolidBrush(Color.FromArgb(15, GlowColor)))
    for (int x = 0; x <= GlowAmount; x++)
        for (int y = 0; y <= GlowAmount; y++)
            g.DrawString(Text, this.Font, br, new Point(IconOffset + x, y));

Vous pouvez également obtenir l'avantage supplémentaire de chaîner usingsensemble sans avoir à indenter un million de fois.

using (Graphics g = Graphics.FromImage(bmp))
{
    using (Brush brush = new SolidBrush(backgroundColor))
    {
        using (Pen pen = new Pen(Color.FromArgb(penColor)))
        {
            //do lots of work
        }
    }
 }
//versus
using (Graphics g = Graphics.FromImage(bmp))
using (Brush brush = new SolidBrush(backgroundColor))
using (Pen pen = new Pen(Color.FromArgb(penColor)))
{
    //do lots of work
}

L'argument le plus courant pour les accolades tourne autour de la programmation de la maintenance et des problèmes qui en découleraient en insérant du code entre l'instruction if d'origine et son résultat attendu:

if (foo)
    Bar();
    Biz();

Des questions:

  1. Est-il faux de vouloir utiliser la syntaxe plus compacte qu'offre le langage? Les gens qui conçoivent ces langages sont intelligents, je ne peux pas imaginer qu'ils mettraient une fonctionnalité toujours mauvaise à utiliser.
  2. Devrions-nous ou ne devrions-nous pas écrire du code afin que le plus petit dénominateur commun puisse le comprendre et n'ait aucun problème à l'utiliser?
  3. Y a-t-il un autre argument qui me manque?

6
Je suis d'accord avec toi. Omettez-les. Période.
Andrei Rînea

68
QUI SE SOUCIE DU NOMBRE DE LIGNES QUELQUE CHOSE C'EST EN 2010. Les moniteurs sont larges, bon marché et haute résolution! Mon moniteur mesure 2048 X 1152 et j'en ai DEUX! La lisibilité est bien plus importante que la sauvegarde de 2 lignes verticales lorsque vous pouvez facilement introduire des erreurs subtiles difficiles à trouver.

51
Les moniteurs sont larges et bon marché, mais ils ne sont pas grands et bon marché. L'espace vertical est plus rare que l'espace horizontal.
Adam dit - Réintègre Monica le

32
@AdamRuth Tournez-les sur le côté :)
Zachary Yates

16
Donc, vous ne vous trompez pas comme Apple avec le bogue SSL trouvé en février 2014, LOL.
learnvst

Réponses:


184

En fait, la seule fois où je me suis vraiment mordu, c'était quand je déboguais et commentais bar ():

if(foo)
  // bar();
doSomethingElse();

En dehors de cela, j'ai tendance à utiliser:

if(foo) bar();

Ce qui prend en charge le cas ci-dessus.

EDIT Merci d'avoir clarifié la question, je suis d'accord, nous ne devrions pas écrire de code au plus petit dénominateur commun.


31
C'est approximatif bien sûr, mais je pense que le plus gros problème pour les responsables est qu'ils vont ajouter une deuxième ligne, sans se rendre compte que cela ne fait pas partie de l'instruction conditionnelle même si cela semble VRAIMENT le faire.
danieltalsky

23
Je n'aime pas le style à une seule doublure parce que je cherche toujours le corps à boucle ci-dessous.
Nosredna

18
Je trouve le style one-liner plus irritant qu'utile parce que (surtout dans l'imbrication profonde - ugh) la déclaration peut être facilement dépassée et la confusion peut s'ensuivre. J'utilise presque exclusivement ces ifs à instruction unique pour la validation d'entrée (c'est-à-dire les retours anticipés) ou le contrôle de boucle (par exemple, en ignorant les noms de fichiers non pertinents dans les parcours du système de fichiers), où les lignes vides aident à les désactiver du code principal.
Alan Plum

1
Le style sur une ligne masque également la barre () de la couverture de test. Il semblera couvert même si foo est toujours faux.
Bohumil Janda

1
C'est une autre façon de dire, "si la source avait inclus les accolades, je n'aurais pas perdu de temps lors du débogage." - l'ajout des accolades est trivialement simple et évite de laisser des pièges à la personne suivante. Le seul argument contre est la «lisibilité», ce qui est assez ténu, étant donné qu'il s'agit d'un cas où quelque chose se produit implicitement si vous les omettez.
Andrew Theken

157

Vitesse de lecture ...

Hormis ce qui a déjà été mentionné. À ce stade, j'ai déjà été conditionné pour analyser les déclarations if avec des accolades et un espace blanc. Alors j'ai lu:

if (condition)
{
    DoSomething();
}

DoSomethingElse();

Un peu plus vite que je ne l'ai lu:

if (condition) DoSomething();

DoSomethingElse();

Je le lis un peu plus lentement s'il ressemble à ceci:

if (condition) DoSomething();
DoSomethingElse();

J'ai lu ceci beaucoup plus lentement que le précédent:

if (condition) 
    DoSomething();
DoSomethingElse();

parce que je ne peux pas m'empêcher de le relire au cas où et je me demande si l'auteur a l'intention:

if (condition)
{
    DoSomething();
    DoSomethingElse();
}

Déjà couvert en général, mais quand il s'agit de lire ce qui suit, je vais examiner cela pendant un certain temps pour m'assurer de ce que l'auteur a voulu. Je peux même traquer l'auteur original pour confirmer.

if (condition) 
    DoSomething();
    DoSomethingElse();

29
Le problème est résolu lorsque, dans votre 4ème échantillon, vous venez de mettre une ligne vide après l'instruction if pour la séparer de DoSomethingElse () C'est ce que je fais et la lisibilité est pratiquement la même qu'avec le 1er échantillon (sinon mieux ;-P) Une autre chose est que mettre les lignes en groupes de 2 ou 3 aide considérablement la lisibilité, il vous suffit de parcourir le code beaucoup plus rapidement.
Piotr Owsiak

6
C'est peut-être parce que je suis habitué à Python, mais mettre la première accolade sur la même ligne que l'instruction if me permet de le lire + le comprendre encore plus rapidement.
Ponkadoodle

16
Le problème avec le style sans bretelles vous fait perdre votre précieuse concentration à vous demander si le bloc a des accolades plutôt que des choses plus importantes. Cela seul est une raison suffisante pour utiliser la convention la plus simple possible, qui est toujours des accolades.
Nate CK

2
Les accolades sont explicites par nature. Je vais m'en tenir à ça, merci.
TheOptimusPrimus

2
Dans le dernier cas, traquez l'auteur original et donnez-lui une fessée ...;)
Per Lundberg

55

Si c'est quelque chose de petit, écrivez-le comme ceci:

if(foo()) bar();

S'il est assez long pour se diviser en deux lignes, utilisez des accolades.


ouais, c'est ce que je fais aussi. Cela vous oblige à ajouter des accolades si vous ajoutez une autre ligne, et il est assez clair de voir que bar () fait partie du if, donc de mauvaises choses se produiront si vous le commentez simplement.
jalf

10
Pas très convivial pour le débogueur, cependant. Comment mettre en place un point d'arrêt sur la partie "barre"?
Nemanja Trifunovic

9
@Nemanja: placez simplement votre curseur sur bar (); et appuyez sur F9. VS2005 et VS2008 gèrent les points d'arrêt intra-ligne, s'ils sont des "instructions" séparées.
GalacticCowboy

4
GalanticCowboy: Il y a plus d'environnements que ceux que vous connaissez. :-)

20
Bien sûr, mais comme le contexte est C #, cela devrait couvrir une majorité significative des utilisateurs ...
GalacticCowboy

48

J'avais aussi l'habitude de penser qu'il était préférable de n'utiliser des accolades qu'en cas de besoin. Mais plus maintenant, la principale raison, lorsque vous avez beaucoup de code, cela le rend plus lisible et vous pouvez analyser le code plus rapidement lorsque vous avez un style de contreventement cohérent.

Une autre bonne raison pour toujours utiliser des accolades, en plus de quelqu'un qui ajoute une deuxième instruction au if, est que quelque chose comme ça pourrait arriver:

if(a)
   if(b)
     c();
else
   d();

Avez-vous remarqué que la clause else est en fait celle du "si (b)"? Vous l'avez probablement fait, mais feriez-vous confiance à quelqu'un pour être familier avec ce piège?

Donc, si juste pour la cohérence et parce que vous ne savez jamais quelles choses inattendues peuvent se produire quand quelqu'un d'autre (ce sont toujours les autres qui sont stupides) change le code, je mets toujours des accolades, car cela rend le code source plus lisible, plus rapide à analyser ton cerveau. Uniquement pour les déclarations if les plus simples, comme si une délégation est faite ou est de type interrupteur, où vous savez que la clause ne sera jamais étendue, je laisserais les accolades.


12
C'est l'un des deux cas où j'utilise des accolades. Sinon non.
Andrei Rînea

3
Cela devrait plutôt être écrit comme si (a && b) ... en premier lieu methinks.
alexander.biskop

8
@ alexander.biskop: Sûrement pas, car cela donne au bloc else une signification différente ( !a || !b) que celle avec ( !a) ou sans ( a && !b) les accolades ajoutées.
Ben Voigt

1
@Ben Voigt: C'est vrai! Je suis tombé dessus ;-) Un an et demi et deux votes positifs plus tard, quelqu'un se rend compte que la déclaration que j'ai faite est fausse ... Je suppose que je n'ai pas prêté suffisamment d'attention aux détails, principalement parce que l'intention derrière mon commentaire était différente de celle de souligner une transformation techniquement correcte de cette clause if. Ce que je voulais dire, c'est que les instructions if en ligne imbriquées réduisent généralement la lisibilité (et en particulier la traçabilité du flux de contrôle) de manière significative à mon humble avis et devraient donc plutôt être combinées en une seule déclaration (ou contournées complètement). Cheers
alexander.biskop

3
@ alexander.biskop: En même temps, le débogage est plus facile avec des ifs imbriqués chacun avec des conditions plus simples, puisque vous pouvez faire un pas sur chacun.
Ben Voigt

35

Cela n'est pas toujours considéré comme une mauvaise pratique. Les directives de codage des projets mono suggèrent de ne pas utiliser d'accolades si ce n'est pas nécessaire. La même chose pour les normes de codage GNU . Je pense que c'est une question de goût personnel, comme toujours avec les normes de codage.


2
Regarder le code Mono me semble assez étranger après avoir lu toute la ligne directrice.
dance2die

35

Les lignes sont bon marché. La puissance du processeur est bon marché. Le temps du développeur est très coûteux.

En règle générale, à moins que je ne développe une application absolument critique en termes de ressources / vitesse, je me trompe toujours du côté de l'écriture de code qui est

(a) Facile pour tout autre développeur de suivre ce que je fais

(b) Commenter des parties spécifiques du code qui peuvent en avoir besoin

(c) Facile à déboguer en cas de problème

(d) Facile à modifier si cela doit être dans le futur (c.-à-d. ajouter / supprimer du code)

La rapidité ou l'élégance académique du code est secondaire à ces facteurs d'un point de vue commercial. Cela ne veut pas dire que je me suis mis à écrire du code maladroit ou laid, mais c'est MON ordre de priorité.

En omettant les accolades dans la plupart des cas, cela rend pour moi (b), (c) et (d) plus difficiles (notez cependant pas impossible). Je dirais que l'utilisation d'accolades ou non n'a pas d'effet sur (a).


9
Votre dernière déclaration concernant (a) est une opinion qu'un grand nombre de développeurs, y compris d'autres affiches ici, diraient.
Kelly

34

Je préfère la clarté qu'offre l'accolade bouclée. Vous savez exactement ce que cela signifie et vous n'avez pas à deviner si quelqu'un a juste fait une gaffe et l'a laissé de côté (et a introduit un bogue). Le seul moment où je les omette, c'est lorsque je mets le if et l'action sur la même ligne. Je ne fais pas ça très souvent non plus. Je préfère en fait l'espace blanc introduit en mettant l'accolade sur sa propre ligne, bien que depuis des années de programmation de type K&R C, terminer la ligne avec une accolade est une pratique que je dois travailler pour surmonter si l'EDI ne l'applique pas pour moi.

if (condition) action();  // ok by me

if (condition) // normal/standard for me
{
   action();
}

23

Je pense que c'est une question de lignes directrices pour le projet sur lequel vous travaillez et de goût personnel.

Je les omets généralement lorsqu'ils ne sont pas nécessaires, sauf dans certains cas comme celui-ci:

if (something)
    just one statement; // i find this ugly
else
{
    // many
    // lines
    // of code
}

je préfère

if (something)
{
    just one statement; // looks better:)
}
else
{
    // many
    // lines
    // of code
}

15

L'un des cas où cela peut vous mordre est de retour dans l'ancien temps des macros C / C ++. Je sais que c'est une question C #, mais souvent les normes de codage sont reportées sans les raisons pour lesquelles la norme a été créée en premier lieu.

Si vous ne faites pas très attention lorsque vous créez vos macros, vous pouvez finir par causer des problèmes avec les instructions if qui n'utilisent pas {}.

#define BADLY_MADE_MACRO(x) function1(x); function2(x);

if (myCondition) BADLY_MADE_MACRO(myValue)

Maintenant, ne vous méprenez pas, je ne dis pas que vous devriez toujours faire {} juste pour éviter ce problème en C / C ++, mais j'ai dû faire face à des bogues très étranges à cause de cela.


2
si seulement tout le code se déclarait comme tel ... soupir
Nathan Strong

15

J'avais l'habitude de penser de la même manière.

Jusqu'au jour où (pourquoi y a-t-il toujours ce «jour» qui change votre vie pour toujours?) Nous passons de 24 à 36 heures d'affilée sans sommeil à déboguer le code de production uniquement pour découvrir que quelqu'un n'a pas mis d'accolades combiné avec un changement de recherche / remplacement .

C'était quelque chose comme ça.

 if( debugEnabled ) 
      println( "About to save 1 day of work to some very important place.");
 saveDayData();

Ce qui est venu après était

 if( debugEnabled ) 
 //     println( "About to save 1 day of work to some very important place.");
 saveDayData();

Il s'avère que le système générait 500 Mo de journaux par jour et on nous a demandé de l'arrêter. L'indicateur de débogage n'était pas suffisant, donc une recherche et un remplacement de println étaient en ordre.

Toujours lorsque l'application est entrée en production, l'indicateur de débogage était désactivé et l'important "saveDayData" n'a jamais été appelé.

ÉDITER

Maintenant, le seul endroit où je n'utilise pas les accolades est dans la construction if / try.

if( object != null ) try { 
     object.close();
} catch( .....

Après avoir regardé un développeur superstar faire cela.


3
Je ne comprends pas. Vous avez une variable qui contrôle le débogage (debugEnabled) et vous utilisez toujours des commentaires pour désactiver le débogage ??? Pourquoi n'avez-vous pas simplement défini debugEnabled sur false?
Igor Popov du

Ce n'est pas exactement le scénario, mais vous faites un bon point. Des choses stupides (comme ne pas définir debug sur false) créent des bogues subtils et stupides qui sont plus difficiles à trouver que des bogues "évidents". Ne pas utiliser d'accolades n'a pas trop aidé dans ce cas.
OscarRyz

1
@igor Et parce qu'ils voulaient simplement supprimer une ligne de journalisation, pas toutes les lignes de journalisation?
gman

14

Pour être franc, je le vois comme:

Les bons programmeurs programment de manière défensive, les mauvais programmeurs non.

Puisqu'il y a plusieurs exemples ci-dessus et mes propres expériences similaires avec des bugs liés à l'oubli des accolades, j'ai appris à la dure façon de TOUJOURS METTRE DES BRACELETS.

Tout le reste consiste à choisir un style personnel plutôt que la sécurité et c'est clairement une mauvaise programmation.

Joel mentionne même cela dans Making Wrong Code Look Wrong

Une fois que vous êtes mordu par un bogue à cause d'accolades manquantes, vous apprenez que les accolades manquantes ne semblent pas correctes parce que vous savez que c'est un endroit potentiel pour qu'un autre bogue se produise.


Si des accolades ouvertes sont placées sur des lignes par elles-mêmes, alors n'importe quel endroit où deux lignes ou plus sont indentées sans paire d'accolades aura l'air incorrect, tout comme toute paire d'accolades sans correspondance. Une telle utilisation coûtera une ligne vide dans les cas où une ifinstruction contrôle un bloc, mais évitera le besoin d'un bloc dans les cas où une ifinstruction contrôle une seule action plutôt qu'un bloc.
supercat

14

Je suis très heureux de:

foreach (Foo f in foos)
  foreach (Bar b in bars)
    if (f.Equals(b))
      return true;

return false;

Personnellement, je ne vois pas pourquoi

foreach (Foo f in foos)
{
  foreach (Bar b in bars)
  {
    if (f.Equals(b))
    {
      return true;
    }
  }
}

return false;

est plus lisible.

Oui, les lignes sont gratuites, mais pourquoi devrais-je faire défiler les pages et les pages de code alors qu'il pourrait faire la moitié de la taille?

S'il y a une différence de lisibilité ou de maintenabilité, alors, bien sûr, mettez des accolades ... mais dans ce cas, je ne vois aucune raison de le faire.

De plus, je mettrai toujours des accolades pour les if imbriqués là où j'ai imbriqué les autres

if (condition1)
  if (condition2)
    doSomething();
  else (condition2)
    doSomethingElse();

contre

if (condition1)
  if (condition2)
    doSomething();
else (condition2)
  doSomethingElse();

est terriblement déroutant, donc je l'écris toujours comme:

if (condition1)
{
  if (condition2)
    doSomething();
  else (condition2)
    doSomethingElse();
}

Dans la mesure du possible, j'utilise des opérateurs ternaires, mais je ne les imbrique jamais .


je viens de voir cela presque se produire dans mon code :) je me suis dit que je vais jeter un coup d'œil autour de moi, et voilà ... c'est déjà là-bas :)
Noctis

10

Je conviens que "si vous êtes assez intelligent pour que quelqu'un vous paie pour écrire du code, vous devriez être assez intelligent pour ne pas vous fier uniquement à l'indentation pour voir le flux du code."

Cependant ... des erreurs peuvent être commises, et celle-ci est difficile à déboguer ... surtout si vous venez en regardant le code de quelqu'un d'autre.


10

Ma philosophie est que si cela rend le code plus lisible, pourquoi ne pas le faire?

De toute évidence, vous devez tracer la ligne quelque part, comme trouver le juste milieu entre les noms de variables concis et trop descriptifs. Mais les parenthèses évitent vraiment les erreurs et améliorent la lisibilité du code.

Vous pouvez affirmer que les gens assez intelligents pour être des codeurs le seront assez pour éviter les bogues qui provoquent des déclarations sans parenthèses. Mais pouvez-vous honnêtement dire que vous n'avez jamais été trébuché par quelque chose d'aussi simple qu'une faute d'orthographe? Des minuties comme celle-ci peuvent être accablantes lorsqu'on regarde de grands projets.


7
Bien sûr, c'est très subjectif. Les laisser de côté améliore parfois la lisibilité.
Brian Knoblauch

Certes, si jamais je laisse les crochets de côté, je garde une ligne, comme d'autres l'ont mentionné. J'ai été mordu trop de fois mais des déclarations sans parenthèses sur plusieurs lignes. Même si vous savez faire attention à cela, cela peut toujours vous attraper.
James McMahon

10

Il y a toujours des exceptions, mais je dirais contre l'omission d'accolades uniquement lorsque c'est dans l'une des formes:

if(x == y)
   for(/* loop */)
   {
      //200 lines
   }

//rampion's example:
for(/* loop */)
{
   for(/* loop */)
      for(/* loop */)
      {
         //several lines
      }
}

Sinon, je n'ai aucun problème avec ça.


4
Mauvais exemples. Dans ces deux cas, je factoriserais cette ligne de 200 pour la boucle dans sa propre méthode, ou de préférence plusieurs méthodes.
Adam Jaskiewicz

2
C'est vrai, mais cela arrive. De plus, chaque fois qu'un bloc est plus long que l'écran du lecteur est élevé, vous rencontrez ce problème. Et vous ne pouvez pas contrôler la hauteur de l'écran de votre lecteur de code. Ils pourraient ne voir que quelques lignes de chaque côté.
rampion

2
Cela arrive. Cela ne veut pas dire que cela devrait arriver.
Adam Jaskiewicz

3
@AdamJaskiewicz C'est vrai. Cela arrive. Nous devons penser à ce qui se passe, plutôt qu'à ce qui devrait arriver. Si nous pouvions nous limiter à ce qui devrait arriver, nous n'aurions pas à nous soucier des bogues.
Beska

10

J'utilise occasionnellement le code le plus bas (plusieurs instructions using), mais à part cela, je mets toujours les accolades. Je trouve juste que cela rend le code plus clair. Il est manifestement évident, au-delà de la simple indentation, qu'une instruction fait partie d'un bloc (et donc probablement partie d'un if, etc.).

J'ai vu le

if (...)
    foo();
    bar();

bug m'a mordu (ou plutôt "moi et collègues" - je n'ai pas réellement introduit le bug) une fois . C'était en dépit du fait que nos normes de codage à l'époque recommandaient d'utiliser des accolades partout. Il m'a fallu un temps étonnamment long pour repérer - parce que vous voyez ce que vous voulez voir. (C'était il y a environ 10 ans. Peut-être que je le trouverais plus vite maintenant.)

Bien sûr, si vous utilisez "accolade à la fin de la ligne", cela réduit les lignes supplémentaires encourues, mais personnellement, je n'aime pas ce style de toute façon. (Je l'utilise au travail et je l'ai trouvé moins désagréable que prévu, mais c'est quand même un peu désagréable.)


Je soutiens toujours que la cohérence est plus importante que le style réel, pourquoi devrions-nous faire une exception uniquement dans le cas des utilisations?
Bob

@Bob: Bon point, et je ne le fais qu'occasionnellement. Je n'aimerais pas prétendre que j'ai des raisons réelles ici :) En fait, il y a une raison raisonnable - imbriquer les utilisations (et uniquement les utilisations) comme cela est assez évident, et vous vous retrouvez toujours avec un blocage. Je ne vois pas immédiatement le danger.
Jon Skeet

Ce qui ne veut pas dire qu'il n'y a pas de danger, bien sûr.
Jon Skeet

1
Meilleure solution à ce bogue: utilisez Python. (Je plaisante, bien sûr.)
Joel Wietelmann

10

Je suis impressionné et honoré que mes pairs dans ce domaine de la programmation informatique (vous beaucoup) ne soient pas découragés par la perspective de bogues potentiels lorsque vous sautez les accolades sur des blocs d'une seule ligne.

Je suppose que cela signifie que je ne suis pas intelligent. J'ai commis des erreurs à plusieurs reprises. J'ai débogué les erreurs des autres à ce sujet. J'ai regardé le logiciel livrer avec des bogues à cause de cela (RDP à une machine exécutant VS2002 et votre police de fenêtre de surveillance deviendra bancale).

Si je regarde toutes les erreurs que j'ai faites qui auraient pu être évitées avec un changement de style de codage, la liste est très longue. Si je n'avais pas changé mon approche dans chacun de ces cas, je ne l'aurais probablement jamais fait en tant que programmeur. Encore une fois, je suppose que je ne suis pas intelligent. Pour compenser, je suis un fervent utilisateur d'accolades sur des blocs à une seule ligne depuis longtemps.

Cela dit, certaines choses ont changé dans le monde qui rendent la règle "tu utiliseras des accolades sur des blocs à une seule ligne" moins pertinente aujourd'hui que lorsque Moïse nous l'a rapportée:

  • Certains langages populaires font disparaître le problème en obligeant l'ordinateur à lire l'indentation, tout comme le fait le programmeur (par exemple Python).

  • Mon éditeur formate automatiquement pour moi, donc les chances de me tromper par indentation sont beaucoup réduites.

  • TDD signifie que si j'introduis un bogue parce que je suis confus par un bloc d'une seule ligne, je suis beaucoup plus susceptible de découvrir le bogue rapidement.

  • Le refactoring et l'expressivité du langage signifient que mes blocs sont beaucoup plus courts et que les blocs sur une seule ligne se produisent beaucoup plus souvent que d'habitude. Hypothétiquement, avec une application impitoyable d'ExtractMethod, je pourrais peut-être n'avoir que des blocs d'une seule ligne dans tout mon programme. (Je me demande à quoi cela ressemblerait?)

En fait, il y a un avantage distinct à refactoriser sans pitié et à omettre les accolades sur les blocs à une seule ligne: quand vous voyez des accolades, une petite alarme peut se déclencher dans votre tête qui dit "complexité ici! Attention!". Imaginez si c'était la norme:

if (condition) Foo();   // normal, everyday code

if (condition) 
{
    // something non-trivial hapening; pay attention!
    Foo();
    Bar();
}

Je m'ouvre à l'idée de changer ma convention de codage en quelque chose comme "les blocs sur une seule ligne peuvent ne jamais avoir d'accolades" ou "si vous pouvez mettre le bloc sur la même ligne que la condition, et tout tient dans les 80 caractères, omettez les accolades ". Nous verrons.


En tant qu'ancien programmeur Java, je suis tout à fait d'accord avec le fait que le formatage automatisé est la vraie réponse au problème. Vous n'avez même pas besoin que votre éditeur ajoute des accolades automatiquement - l'indentation automatique à elle seule peut aider à éviter beaucoup d'ambiguïtés. Bien sûr, maintenant que je suis passé à Python, je me suis habitué à formater correctement mon code en premier lieu.
Alan Plum

Je ressens la même chose avec les accolades. Tout est question de complexité. Idéalement, nous n'aurions qu'un seul bloc de ligne. C'est ce que j'appelle la lisibilité, pas des accolades inutiles.
Igor Popov

9

Sur les trois conventions:

if(addCurleyBraces()) bugFreeSofware.hooray();

et:

if(addCurleyBraces())
    bugFreeSofware.hooray();

et (qui représentent n'importe quel style d'indentation utilisant une accolade ouvrante et fermante):

if(addCurleyBraces()) {
    bugFreeSofware.hooray();
}

Je préfère le dernier comme:

  • Je trouve qu'il est plus facile de lire si toutes les instructions if sont écrites de manière uniforme.
  • Cela peut rendre le logiciel un peu plus robuste et sans bogue. Cependant, tous les IDE modernes et les éditeurs de texte avancés ont de jolies fonctionnalités d'indentation automatique que je pense que tout le monde devrait utiliser tant que cela ne gâche pas le formatage des commentaires ou ne va pas à l'encontre des normes de l'équipe (dans de nombreux cas, il est possible de créer un schéma de formatage personnalisé et partagez-le avec l'équipe). Mon point ici est que si l'indentation est effectuée correctement, le risque d'introduction de bogue est un peu réduit.
  • Je préfère que l'expression booléenne et les instructions à exécuter soient sur des lignes différentes. J'aime pouvoir marquer une ligne à des fins de débogage. Même si j'utilise un IDE où je peux marquer une instruction et y accéder, c'est une opération interactive et je pourrais oublier où j'ai commencé à déboguer ou du moins il me faudra un peu plus de temps pour parcourir le code plusieurs fois (car je dois marquer la position manuellement à chaque fois pendant le débogage).

8

Vos principaux arguments contre l'utilisation d'accolades sont qu'ils utilisent des lignes supplémentaires et qu'ils nécessitent une indentation supplémentaire.

Les lignes sont (presque) libres, minimiser le nombre de lignes dans votre code ne devrait pas être un objectif.

Et l'indentation est indépendante de l'utilisation d'accolades. Dans votre exemple «d'utilisation» en cascade, je pense toujours que vous devriez les mettre en retrait même lorsque vous omettez les accolades.


8

Je crois fermement à l'écriture de code ordonné et concis, mais j'utiliserais toujours des accolades. Je trouve qu'ils sont un moyen pratique de voir rapidement la portée dans laquelle une ligne de code particulière existe. Il n'y a pas d'ambiguïté, c'est simplement exposé explicitement devant vous.

Certains peuvent dire que c'est un cas de préférence, mais je trouve le flux logique d'un programme beaucoup plus facile à suivre s'il est cohérent en interne, et je ne pense pas qu'il soit cohérent d'écrire une instruction IF comme celle-ci;

if(x < y)
    x = y;
else
    y = x;

Et un autre comme celui-ci;

if(x < y)
{
    x = y;
    x++;
}
else
{
    y = x;
    y++;
}

Je préfère simplement choisir un style général et m'en tenir à lui :)


7

L' un des principaux problèmes est quand vous avez des régions d'une seule ligne et non un liners, ainsi que la séparation de la statment de commande ( for, if, qu'avez-vous) et la fin de la statment.

Par exemple:

for (...)
{
  for (...)
    for (...) 
    {
      // a couple pages of code
    }
  // which for block is ending here?  A good text editor will tell you, 
  // but it's not obvious when you're reading the code
}

4
Pourquoi avez-vous quand même quelques pages de code dans votre boucle for?
Adam Jaskiewicz

b / c Je suis une motte insensible, et je suis obsédé par le fait de me débarrasser du "coût" des appels de fonction. :)
rampion

4
Les deux pages de code doivent généralement être dans une fonction distincte.
Jonathan Leffler

1
excusez-moi, je voulais dire que je jouais le rôle d'une telle motte. Cependant, je soutiens que le même problème peut se produire pour des régions plus courtes, lorsqu'elles sont vues à travers une petite fenêtre. Et c'est hors du contrôle du codeur.
rampion

7

J'étais un grand partisan de "les accolades sont un must!", Mais depuis l'adoption des tests unitaires, je trouve que mes tests unitaires protègent les déclarations sans accolades contre les scénarios comme:

if (foo)
    snafu();
    bar();

Avec de bons tests unitaires, je peux en toute confiance omettre les accolades pour les déclarations simples afin d'améliorer la lisibilité (oui, cela peut être subjectif).

Alternativement, pour quelque chose comme ce qui précède, je voudrais probablement que cela ressemble à:

if (foo) snafu();

De cette façon, le développeur qui a besoin d'ajouter bar () à la condition serait plus apte à reconnaître l'absence d'accolades et à les ajouter.


2
Vous avez dit "je n'en ai pas besoin" puis avez donné une raison pour l'utiliser: la lisibilité!
tvanfosson

4
Je ne me fierais pas à un test unitaire pour trouver cela. LINT peut-être, test unitaire non!
Kristen

2
@Kristen - L'idée du test unitaire est d'affirmer le comportement de la méthode. Si le comportement change (comme décrit ci-dessus), le test unitaire échouera. Je ne vois pas le problème là-dedans.
Liggy

Mais pourquoi se fier au test unitaire pour identifier l'évidence qui devrait être corrigée avant de passer à UT?
Andrew du

7

Faites preuve de jugement personnel.

if (foo)
  bar();

est très bien en soi. À moins que vous ne soyez vraiment inquiet que des crétins mettent quelque chose comme ça plus tard:

if (foo)
  bar();
  baz();

Si vous n'êtes pas inquiet pour les crétins, tout va bien (je ne le suis pas - s'ils ne parviennent pas à obtenir la syntaxe de base du code, c'est le moindre de leurs problèmes)>

En échange, c'est beaucoup plus lisible.

Le reste du temps:

if (foo) {
  bar();
  baz();
}

Ce qui a été mon préféré aussi longtemps que je me souvienne. Aditionellement:

if (foo) {
  bar();
  baz();
} else {
  qux();
}

Travaille pour moi.

L'espace vertical en lui-même n'est pas très pertinent, la lisibilité l'est. L'accolade ouvrante sur une ligne arrête à elle seule la conversation pour un élément syntaxique, jusqu'à ce que votre œil se déplace vers la ligne suivante. Pas ce que j'aime.


Le seul moment où je préfère le premier style, c'est quand je dois revenir immédiatement ou lancer une erreur au cas où quelque chose ne va pas. Comme if (parameter == null) return null;.
nawfal

7

D'accord, c'est une vieille question à laquelle on a répondu à mort. J'ai quelque chose à ajouter.

Tout d'abord, je dois juste dire UTILISER LES BRACELETS. Ils ne peuvent que contribuer à la lisibilité, et la lisibilité (pour vous-même et pour les autres!) Devrait être très élevée sur votre liste de priorité, sauf si vous écrivez l'assembly. Le code illisible conduit toujours à des bogues. Si vous trouvez que les accolades font prendre trop de place à votre code, vos méthodes sont probablement trop longues. La plupart ou la totalité des méthodes doivent tenir dans une hauteur d'écran si vous le faites correctement, et Find (F3) est votre ami.

Maintenant, pour mon ajout: il y a un problème avec ceci:

if (foo) bar();

Essayez de définir un point d'arrêt qui ne sera atteint que si bar () va s'exécuter. Vous pouvez le faire en C # en plaçant le curseur sur la seconde moitié du code, mais ce n'est pas évident et c'est un peu pénible. En C ++, vous ne pouviez pas du tout le faire. Un de nos développeurs les plus expérimentés travaillant sur du code C ++ insiste pour briser les instructions «if» en deux lignes pour cette raison. Et je suis d'accord avec lui.

Alors fais ceci:

if (foo)
{
    bar(); //It is easy to put a breakpoint here, and that is useful.
}

2
Faites un clic droit sur la barre et choisissez Insérer un point d'arrêt ... Pas difficile du tout. Connaissez vos outils.
Bob

Un clic droit sur la barre d'indicateur ne fait rien; voulez-vous dire un clic droit sur le texte? Quoi qu'il en soit, si vous voulez que le point de rupture ne soit atteint que lorsque l'instruction "if" est vraie et que "bar ()" est sur sa propre ligne, vous pouvez placer le curseur n'importe où sur cette ligne et appuyer sur F9, ou cliquer avec le bouton gauche sur le bouton marge de l'indicateur. Si, cependant, tout le code est sur une seule ligne, vous devez positionner le curseur sur "bar ()" ou faire un clic droit exactement là avant d'appuyer sur F9, et cliquer sur la marge de l'indicateur ne fonctionnera pas (place le point d'arrêt sur le ' si'). Ce n'est pas «difficile», mais cela demande moins de concentration lorsque le code est sur deux lignes.
stone

Oh, ha ha, faites un clic droit sur "bar ()". Vous vouliez dire le texte. Je t'ai eu. Bien sûr, ou appuyez simplement sur F9 ...
stone

>> vous devez positionner le curseur sur "bar ()" ou faire un clic droit exactement là avant d'appuyer sur F9, (je voulais dire positionner le curseur exactement là avant d'appuyer sur F9 ou de faire un clic droit)
pierre

7

afin d'éviter que le code avec accolades ne prenne beaucoup de place, j'utilise la technique recommandée dans le livre Code Complete :

if (...) {
    foo();
    bar();
}
else {
    ...
}

Je ne comprends pas pourquoi il a été downmodded, il économise une ligne pour chaque paire de supports que je l'utilise tout le temps
Eric

2
Ceci est plus connu sous le nom de style K&R. Basé sur le livre The C Programming Language de Kernighan et Ritchie: en.wikipedia.org/wiki/The_C_Programming_Language_(book) . Et cela ne devrait pas vous déranger.
jmucchiello

Merci! J'ai pensé que c'était juste un goût personnel. J'avais l'habitude de trouver cette syntaxe ennuyeuse moi-même, mais je l'ai adoptée après avoir lu Code Complete, et je l'apprécie vraiment maintenant.
Nathan Prather le

Je lisais toutes les réponses ci-dessus en pensant "pourquoi personne n'a encore suggéré cela ???" Il aligne le crochet fermant avec le bloc qu'il ferme, c'est-à-dire "si" ou "while", etc., pas un "{" dénué de sens. +1.
nickf

Si les accolades ouvertes sont toujours placées sur les lignes par elles-mêmes, alors un ifqui est suivi d'une seule ligne en retrait peut être visuellement reconnu comme contrôlant une seule instruction sans avoir besoin d'accolades. Le style ouvert-accolades-par-lui-même économise ainsi des espaces dans la situation où une ifinstruction contrôle quelque chose qui est sémantiquement une action unique (par opposition à une séquence d'étapes qui ne contient qu'une seule étape). Par exemple, if (someCondition)/ `throw new SomeException (...)`.
supercat

6

Disons que vous avez du code:

if (foo)
    bar();

puis quelqu'un d'autre arrive et ajoute:

if (foo)
    snafu();
    bar();

Selon la façon dont il est écrit, bar (); est maintenant exécutée sans condition. En incluant les accolades, vous évitez ce genre d'erreur accidentelle. Le code doit être rédigé de manière à rendre ces erreurs difficiles ou impossibles à commettre. Si je faisais une revue de code et voyais les accolades manquantes, en particulier réparties sur plusieurs lignes, je créerais un défaut. Dans les cas où cela est justifié, conservez-le sur une seule ligne afin que les chances de commettre une telle erreur soient à nouveau réduites au minimum.


Ce point était déjà soulevé dans la question.
Mike Scott

Pas tout à fait, en fait. Oui, il a mentionné le potentiel de ce type de bogue, mais je parlais de rendre votre code à l'épreuve des bogues et de supprimer le potentiel d'erreur dans le cadre des meilleures pratiques.
Elie

Existe-t-il vraiment un code de preuve de bogue?
Bob

Non, mais vous pouvez rendre les choses plus difficiles. Lisez "Best Kept Secrets of Peer Code Review" de Jason Cohen (voir le lien sur le côté de certaines pages ici) pour avoir une meilleure idée de pourquoi vous faites cela.
Elie

Qui est ce Mike Scott et pourquoi est-il la police de réponse? Cela me fait toujours peur que les gens doivent dire ce qui est évident. Alors pourquoi Mike n'a-t-il pas continué à commenter la description ajoutée que les utilisateurs publient à propos de ce problème? Toutes les réponses ne font-elles pas référence à la question?
bruceatk

6

Réduire les lignes n'est pas vraiment un bon argument pour abandonner les accolades. Si votre méthode est trop volumineuse, elle devrait probablement être refactorisée en morceaux plus petits ou restructurée. Faire cela augmentera sans aucun doute la lisibilité plus que simplement retirer des accolades.


5

Je les omets toujours lorsque c'est approprié, comme dans votre premier exemple. Un code propre et concis que je peux voir et comprendre en jetant un œil est plus facile à maintenir, à déboguer et à comprendre que le code que je dois faire défiler et lire ligne par ligne. Je pense que la plupart des programmeurs seront d'accord avec cela.

Il est facile pour cela de devenir incontrôlable si vous commencez à faire plusieurs imbrications, clauses if / else et ainsi de suite, mais je pense que la plupart des programmeurs devraient être capables de dire où tracer la ligne.

Je vois un peu comme l'argument en faveur if ( foo == 0 )vs if ( 0 == foo ). Ce dernier peut éviter les bogues pour les nouveaux programmeurs (et peut-être même parfois pour les vétérans), tandis que le premier est plus facile à lire et à comprendre rapidement lorsque vous gérez du code.


4

La plupart du temps, il est enraciné en tant que norme de codage, que ce soit pour une entreprise ou un projet FOSS.

En fin de compte, quelqu'un d'autre devra grok votre code et c'est une perte de temps importante pour chaque développeur d'avoir à comprendre le style spécifique de la section de code sur laquelle il travaille.

Aussi, imaginez que quelqu'un passe entre Python et un langage Cish plus d'une fois par jour ... En Python l'indentation fait partie du bloc symantique du langage et il serait assez facile de faire une erreur comme celle que vous citez.


+1 pour un commentaire sur python. Je suis toujours étonné de voir à quel point je peux être "stupide" lorsque je passe continuellement d'une langue à l'autre.
Kena du

3

Optez pour une solution plus sécurisée - juste un autre bogue que vous n'aurez potentiellement pas à corriger.

Personnellement, je me sens plus en sécurité si tous mes blocs sont enveloppés dans des boucles. Même pour les one-liners, ce sont des notations simples qui évitent facilement les erreurs. Cela rend le code plus lisible dans le sens où vous voyez clairement ce qu'il y a dans le bloc pour ne pas confondre le corps du bloc avec les instructions suivantes en dehors du bloc.

Si j'ai un one-liner, je le formate généralement comme suit:

if( some_condition ) { do_some_operation; }

Si la ligne est trop encombrante, utilisez ce qui suit:

if( some_condition )
{
    do_some_operation;
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.