Style et recommandations de commenter le code

26

Je veux avoir de vos conseils et expérience d'écriture de commentaires dans votre code. Comment les rédigez-vous de la manière la plus simple et informative? Quelles habitudes avez-vous lorsque vous commentez des parties de code? Peut-être quelques recommandations exotiques?

J'espère que cette question recueillera les conseils et recommandations les plus intéressants pour commenter, quelque chose d'utile dont tout le monde peut apprendre.

OK, je vais commencer.

  1. Habituellement, je n'utilise pas de /* */commentaires même lorsque je dois commenter plusieurs lignes.

    Avantages : le code est visuellement meilleur que lorsque vous mélangez une telle syntaxe avec des commentaires sur une ligne. La plupart des IDE ont la possibilité de commenter le texte sélectionné et ils le font généralement avec une syntaxe sur une ligne.

    Inconvénients : Difficile d'éditer un tel code sans IDE.

  2. Placez "point" à la fin de tout commentaire terminé.

    Par exemple:

    //Recognize wallpaper style. Here I wanted to add additional details
    int style = int.Parse(styleValue);
    //Apply style to image.
    Apply(style);
    

    Avantages : ne placez "point" que dans les commentaires que vous avez terminés. Parfois, vous pouvez écrire des informations temporelles, donc le manque de "point" vous indiquera que vous vouliez revenir et ajouter du texte supplémentaire à ce commentaire.

  3. Aligner le texte dans les énumérations, les paramètres de commentaire, etc.

    Par exemple:

    public enum WallpaperStyle
    {
        Fill = 100,     //WallpaperStyle = "10"; TileWallpaper = "0".
        SizeToFit = 60, //WallpaperStyle = "6";  TileWallpaper = "0".
        Stretch = 20,   //WallpaperStyle = "2";  TileWallpaper = "0".
        Tile = 1,       //WallpaperStyle = "0";  TileWallpaper = "1".
        Center = 0      //WallpaperStyle = "0";  TileWallpaper = "0".
    };
    

    Avantages : semble juste mieux et visuellement plus facile à trouver ce dont vous avez besoin.

    Inconvénients : Passer du temps à s'aligner et plus difficile à éditer.

  4. Écrivez du texte dans un commentaire que vous ne pouvez pas obtenir en analysant le code.

    Par exemple, commentaire stupide:

    //Apply style.
    Apply(style);
    

    Avantages : Vous aurez un code clair et petit avec seulement des informations utiles dans les commentaires.

Kyrylo M
la source
2
Aligner les commentaires dans vim: utilisez Align.vim et faites :3,7 Align //pour aligner les commentaires sur les lignes 3-7.
Benoit
3
« Difficile à modifier sans IDE » - eh bien, faites - vous que souvent?
3
Je pense qu'une préférence de langue / environnement doit être notée dans la question. Certains ont des directives existantes (.NET a des commentaires xml assez standard: msdn.microsoft.com/en-us/library/b2s063f7.aspx ).
Steven Evers
+1 SnOrfus. Pour les commentaires Java, à utiliser pour les Javadocs, la documentation du développeur doit être placée dans des commentaires à double astérisque, qui doivent être placés avant votre code. Et les commentaires Javadoc sont transformés en html, vous pouvez donc utiliser une liste à puces, un tableau, une image ou une URL dans votre commentaire, et dans tous ces cas, un point de fin peut être dérangeant.
utilisateur inconnu

Réponses:

16

Certaines des déclarations ci-dessous sont assez personnelles, bien qu'avec une certaine justification, et sont censées être de cette façon.

Types de commentaires

Pour la version courte ... J'utilise des commentaires pour:

  • commentaires de fin expliquant les champs dans les structures de données (en dehors de ceux-ci, je n'utilise pas vraiment de commentaires sur une seule ligne)
  • Commentaires multilignes exceptionnels ou orientés vers un objectif au-dessus des blocs
  • documentation utilisateur et / ou développeur publique générée à partir de la source

Lisez ci-dessous pour les détails et les raisons (peut-être obscures).

Commentaires finaux

Selon la langue, en utilisant des commentaires sur une seule ligne ou des commentaires sur plusieurs lignes. Pourquoi cela dépend-il? C'est juste un problème de normalisation. Lorsque j'écris du code C, je préfère le code ANSI C89 à l'ancienne par défaut, donc je préfère toujours l'avoir /* comments */.

Par conséquent, j'aurais cela en C la plupart du temps, et parfois (cela dépend du style de la base de code) pour les langages avec une syntaxe de type C:

typedef struct STRUCT_NAME {
  int fieldA;                /* aligned trailing comment */
  int fieldBWithLongerName;  /* aligned trailing comment */
} TYPE_NAME;

Emacs est sympa et fait ça pour moi avec M-;.

Si le langage prend en charge les commentaires sur une seule ligne et n'est pas basé sur C, je serai plus enclin à utiliser les commentaires sur une seule ligne. Sinon, je crains d'avoir pris l'habitude. Ce qui n'est pas forcément mauvais, car cela m'oblige à être concis.

Commentaires multilignes

Je ne suis pas d'accord avec votre précepte d'utiliser des commentaires sur une seule ligne car cela est plus attrayant visuellement. J'utilise ceci:

/*
 * this is a multi-line comment, which needs to be used
 * for explanations, and preferably be OUTSIDE the a
 * function's or class' and provide information to developers
 * that would not belong to a generated API documentation.
 */

Ou ceci (mais je ne le fais plus souvent, sauf sur une base de code personnelle ou principalement pour des avis de droit d'auteur - c'est historique pour moi et vient de mon éducation. Malheureusement, la plupart des IDE le gâchent lors de l'utilisation du formatage automatique) :

/*
** this is another multi-line comment, which needs to be used
** for explanations, and preferably be OUTSIDE the a
** function's or class' and provide information to developers
** that would not belong to a generated API documentation.
*/

Si besoin est, alors je commenterais en ligne en utilisant ce que j'ai mentionné plus tôt pour les commentaires de fin, s'il est logique de l'utiliser dans une position de fin. Sur un cas de retour très spécial, par exemple, ou pour documenter switchles caseinstructions de a (rare, je n'utilise pas souvent switch), ou lorsque je documente des branches dans un if ... elseflux de contrôle. Si ce n'est pas un de ceux-ci, généralement un bloc de commentaires en dehors de la portée décrivant les étapes de la fonction / méthode / bloc a plus de sens pour moi.

Je les utilise très exceptionnellement, sauf si le codage dans une langue sans prise en charge des commentaires de documentation (voir ci-dessous); auquel cas ils deviennent plus répandus. Mais dans le cas général, c'est vraiment juste pour documenter des choses qui sont destinées à d'autres développeurs et sont des commentaires internes qui doivent vraiment se démarquer. Par exemple, pour documenter un bloc vide obligatoire comme un bloc "forcé" catch:

try {
  /* you'd have real code here, not this comment */
} catch (AwaitedException e) {
  /*
   * Nothing to do here. We default to a previously set value.
   */
}

Ce qui est déjà moche pour moi mais je le tolérerais dans certaines circonstances.

Commentaires sur la documentation

Javadoc et al.

Je les utilise généralement sur les méthodes et les classes pour documenter les versions introduisant une fonctionnalité (ou la changer), surtout si c'est pour une API publique, et pour fournir des exemples (avec des cas d'entrée et de sortie clairs et des cas spéciaux). Bien que dans certains cas, un cas unitaire puisse être préférable pour les documenter, les tests unitaires ne sont pas nécessairement lisibles par l'homme (quel que soit le truc DSL que vous utilisez).

Ils me dérangent un peu pour documenter les champs / propriétés, car je préfère les commentaires de fin pour cela et tous les cadres de génération de documentation ne prennent pas en charge les commentaires de documentation de fin. Doxygen le fait, par exemple, mais pas JavaDoc, ce qui signifie que vous avez besoin d'un commentaire en haut pour tous vos champs. Je peux survivre à cela, car les lignes Java sont de toute façon relativement longues la plupart du temps, donc un commentaire de fin me ferait disparaître également en étendant la ligne au-delà de mon seuil de tolérance. Si Javadoc envisageait de l'améliorer, je serais bien plus heureux.

Code commenté

J'utilise une seule ligne pour une seule raison, dans des langages de type C (sauf si je compile pour un C strict, où je ne les utilise vraiment pas): pour commenter des trucs pendant le codage. La plupart des IDE devront basculer pour les commentaires sur une seule ligne (alignés sur le retrait ou sur la colonne 0), et cela correspond à ce cas d'utilisation pour moi. L'utilisation de la bascule pour les commentaires sur plusieurs lignes (ou la sélection au milieu des lignes, pour certains IDE) rendra plus difficile le basculement entre commentaire / décommentation facilement.

Mais comme je suis contre le code commenté dans le SCM, cela est généralement de très courte durée car je vais supprimer les morceaux commentés avant de valider. (Lisez ma réponse à cette question sur "les commentaires en ligne et les SCM modifiés" )

Styles de commentaire

J'ai généralement tendance à écrire:

  • des phrases complètes avec une grammaire correcte (y compris la ponctuation) pour les commentaires de documentation, car elles sont censées être lues plus tard dans un document API ou même dans le cadre d'un manuel généré.
  • bien formaté mais plus laxiste sur la ponctuation / majuscules pour les blocs de commentaires multilignes
  • blocs de fin sans ponctuation (à cause de l'espace et généralement parce que le commentaire est bref, qui ressemble plus à une déclaration entre parenthèses)

Une note sur la programmation alphabétisée

Vous voudrez peut-être vous intéresser à la programmation littéraire , comme présenté dans cet article par Donald Knuth .

Le paradigme de programmation alphabétisé, [...] représente un abandon de l'écriture de programmes de la manière et de l'ordre imposés par l'ordinateur, et permet plutôt aux programmeurs de développer des programmes dans l'ordre exigé par la logique et le flux de leurs pensées. 2 Les programmes alphabétisés sont écrits comme une exposition ininterrompue de la logique dans un langage humain ordinaire, un peu comme le texte d'un essai [...].

Les outils de programmation alphabétisés sont utilisés pour obtenir deux représentations à partir d'un fichier source alphabétisé: une appropriée pour une compilation ou une exécution ultérieure par un ordinateur, le code "enchevêtré" et une autre pour la visualisation sous forme de documentation formatée, qui est dite "tissée" à partir de la source alphabétisée.

En guise de note secondaire et d'exemple: le cadre JavaScript underscore.js , nonobstant la non-conformité avec mon style de commentaire, est un assez bon exemple d'une base de code bien documentée et d'une source annotée bien formée - bien qu'il ne soit peut-être pas le meilleur à utiliser comme une référence API).


Ce sont des conventions personnelles . Oui, je pourrais être bizarre (et vous pourriez l'être aussi). C'est OK, tant que vous suivez et respectez les conventions de code de votre équipe lorsque vous travaillez avec des pairs, ou n'attaquez pas radicalement leurs préférences et ne cohabitez pas bien. Cela fait partie de votre style, et vous devriez trouver la fine ligne entre le développement d'un style de codage qui vous définit comme un codeur (ou comme un adepte d'une école de pensée ou d'une organisation avec laquelle vous avez un lien) et le respect de la convention d'un groupe pour la cohérence. .

haylem
la source
+1 pour distinguer le code commenté des commentaires de documentation. Je déteste les chasser: P
deltreme
@deltreme: merci. Je ressens ta douleur, j'en chasse moi-même un tas dans mon produit actuel. Les SCM existent pour une raison ... Je suis très tenté d'utiliser simplement une recherche en texte intégral avec une expression régulière dans Eclipse ou Emacs et de les supprimer un par un ... J'ai malheureusement des choses plus productives à faire :(
haylem
Veuillez également consulter cette réponse sur l' utilisation des balises d'action ou de tâche dans les commentaires .
haylem
14

Quand je suis allé à l'université, j'ai toujours appris à commenter chaque ligne de code et chaque en-tête de méthode. Il a été tambouriné / endoctriné à un point tel que vous l'avez fait sans aucun doute. Ayant fait partie de plusieurs équipes de développement Agile dans différentes entreprises, je peux dire que je peux écrire un commentaire une fois dans une lune bleue.

La raison en est double, tout d'abord, nous ne devrions plus écrire de longues méthodes monolithiques qui font 101 choses différentes, la classe, la méthode et les noms de variables devraient être auto-documentés. Prenons l'exemple de la méthode de connexion suivante.

public void Login(string username, string password)
{
    // Get the user entity
    var user = userRepository.GetUser(username);


    // Check that the user exists
    if (user == null)
    {
        throw new UserNotFoundException();
    }

    // Check that the users password matched
    if (user.HashedPassword != GetPasswordHash(password))
    {
        throw new InvalidUsernamePasswordException();
    }

    //Check that the users account has not expired
    if (user.Expired)
    {
        throw new UserExpiredException();
    }

    //Mark user as logged in
    ...
}

Cela peut être réécrit en quelque chose de beaucoup plus lisible et peut-être réutilisable:

public void Login(string username, string password)
{
    var user = GetUserForUsername(username);

    CheckUsersPasswordMatched(user, password);

    CheckUserAccountNotExpired(user);

    MarkUserAsLoggedIn(user);
}

private void User GetUserForUsername(string username)
{
    var user = userRepository.GetUser(username);

    if (user == null)
    {
        throw new UserNotFoundException();
    }
    return user;
}

private void CheckUsersPasswordMatched(User user, string password)
{
    if (user.HashedPassword != GetPasswordHash(password))
    {
        throw new InvalidUsernamePasswordException();
    }
}

private void CheckUserAccountNotExpired(User user)
{
    if (user.Expired)
    {
        throw new UserExpiredException();
    }
}

Vous pouvez voir clairement à partir de la méthode de connexion ce qui se passe. Vous pouvez voir cela comme un travail supplémentaire, mais vos méthodes sont petites et n'ont qu'un seul travail. De plus, les noms de méthode sont descriptifs, il n'est donc pas nécessaire d'écrire de commentaires d'en-tête de méthode. Si vous vous retrouvez avec trop de méthodes, cela indique que les méthodes associées doivent être refactorisées dans un autre objet tel qu'un UserAuthenticationService, rappelez-vous qu'un objet ne doit avoir qu'un seul travail.

Deuxièmement, chaque morceau de code que vous écrivez, y compris les commentaires, doit être conservé, plus vous avez de commentaires, plus il y a à conserver. Si vous renommez une classe ou une variable, vous obtiendrez une erreur de compilation, mais si vous modifiez le fonctionnement d'une section de code ou si vous la supprimez et ne mettez pas à jour les commentaires associés, il n'y aura pas d'erreur de compilation et les commentaires resteront en place causant de la confusion .

Si vous écrivez une API, je pense que toutes les interfaces, classes et énumérations ouvertes au public doivent avoir des commentaires d'en-tête bien écrits pour la documentation.

Bronumski
la source
2
Je suis complètement d'accord avec ça. Les méthodes courtes bien nommées sont auto-documentées. Plus souvent qu'autrement, j'écris très peu (le cas échéant) de commentaires dans le code, et j'écrirai une page wiki assez grande avec des exemples de code (principalement lorsque vous écrivez une bibliothèque que d'autres développeurs utiliseront).
Kevin
2
C'est exactement ce que je suis venu dire ici. En fait, je passe autant de temps à penser aux noms de variables, aux noms de méthode, aux noms de classe, etc., qu'à l'écriture de code. Le résultat, je crois, est un code très supportable. Bien sûr, j'ai parfois des méthodes qui s'appellent quelque chose comme checkIfUnitInvestigationExistsAndCreateNewRootCauseListIfItDoes () ... oui, les noms de méthode PARFOIS deviennent longs, mais je pense que la portabilité du code est l'aspect le plus important du développement (à part la vitesse de publication).
jeremy.mooer
5

Concentrez-vous moins sur le format et plus sur le contenu. Par exemple, les commentaires de votre exemple ne me disent rien de nouveau. Ils sont pires qu'inutiles car ils nuisent à la lecture du code, et de tels commentaires sont au mieux une vague référence à ce que le programmeur original pensait qu'il faisait au moment où il l'a écrit. Je peux voir dans l'exemple de code que vous appliquez un style "appliquer (Style)", je peux lire la source. Je ne peux pas lire dans vos pensées, - pourquoi faites-vous cela, c'est ce que le commentaire devrait me dire. par exemple plutôt que

//Apply style.

Apply(style);

devrait être

// Unlike the others, this image needs to be drawn in the user-requested style apply(style);

La plupart d'entre nous travaillons en équipe sur du code existant, formate comme le reste de l'équipe, comme c'est déjà fait. La cohérence est beaucoup plus importante que jolie.

mattnz
la source
Lisez plus attentivement à quoi sert cet exemple. J'ai déjà mentionné que: "Par exemple, commentaire stupide:".
Kyrylo M
1
Je comprends ton raisonnement. Je suis sûr que vous ne serez pas surpris du nombre de "commentaires stupides" que j'ai vus dans le vrai code, alors je m'en tiens à mon message. le format n'a pas d'importance, le contenu le fait.
mattnz
3

Autant que possible, écrivez votre code de telle sorte que les commentaires soient complètement étrangers. N'ajoutez des commentaires que lorsque le code ne peut pas être écrit de manière à rendre évident un concept important.

Dave
la source
2

Ma propre préférence est de rester très simple. J'évite tout type de mise en forme de fantaisie. La raison principale en est que je pense que le code source devrait être facilement modifiable avec l'éditeur de texte même le plus simple. Je n'emballe jamais non plus les paragraphes de texte, mais laisse plutôt l'éditeur faire un habillage doux (pas d'ajout de sauts de ligne).

Kyrylo M
la source
Je n'ai jamais vu de soft-wrapping dans les commentaires. Je ne pense pas que ce soit une si bonne idée, mais je suppose que c'est bien tant que vous restez cohérent.
Adam Byrtek
2

Je vois souvent des commentaires comme ça, et certains outils le génèrent automatiquement de cette façon:

/** 
 * This is an example, how to waste vertical space,
 * and how to use useless asterixes.
 */

Deux lignes de moins:

/** This is an example, how to spare vertical space,
    and how to avoid useless asterixes. */

Les IDE et les éditeurs, légèrement au-dessus du niveau du bloc-notes, sont capables de détecter les commentaires et de les imprimer dans une couleur différente. Il n'est pas nécessaire de décorer le début de la ligne avec des astérisques.

Vous épargnez même quelques octets, si vous utilisez un onglet pour l'indentation.

Si vous n'utilisez pas un éditeur sophistiqué, qui rend le commentaire dans un ton gris, la grande quantité d'astérisques fonctionnera comme un accent et attirera votre attention, ce qui est l'opposé de la bonne chose à faire: rester derrière.

Utilisateur inconnu
la source
Dans ce cas, les IDE et les éditeurs peuvent utiliser le pliage de code, si votre souci est d'économiser de l'espace sur l'écran. Si votre souci est d'économiser des octets, vous devez arrêter de coder sur vous Commodore 64 :) Plus sérieusement, si vous souhaitez enregistrer des octets (pour le code côté client par exemple), alors un compilateur ou un minifieur le fera pour vous pendant que vous n'aura pas besoin des commentaires en production. La taille du code est importante car plus vous avez de code, plus les risques de bugs sont importants ( sans doute ). Mais la taille totale du fichier ne devrait pas vraiment être un problème dans un processus moderne. Codez le magasin à distance dans un SCM et maintenez-le en conséquence.
haylem
Si vous travaillez avec un éditeur merdique, les astérisques n'attirent pas mon attention car ce sont des commentaires et leur alignement le rend clair. Si je lisais du code pour un langage de script dynamique, alors utiliser votre style avec un éditeur pourri sans aucune mise en évidence serait plus difficile pour moi car cela me prendrait un peu plus de temps pour déterminer si ce que je dis est ou non un bloc de commentaires entier ou une déclaration de code étrangement enveloppé. C'est probablement une personne et le résultat de son habitude, mais c'est ainsi que je le percevrais.
haylem
Je n'aime pas passer mon temps à plier et à déplier du code. Je serais d'accord avec votre argument de base, si les octets avaient un seul avantage, mais ils ne le font pas. Si votre éditeur n'a pas de mise en évidence du code, allez-y, achetez-vous un Commodore64. :) L'argument d'indentation ne tient pas, car si l'indentation sépare le commentaire du code, il sépare également le code du commentaire. Regardez un plus gros morceau de code commenté - un bloc d'astérisques fonctionne comme un accent.
utilisateur inconnu
Comme je l'ai dit, ça pourrait être personnel. Mais pensez-y: voyez-vous vraiment toutes ces publicités brillantes et géniales lorsque vous naviguez sur le Web? La plupart des gens ne le font pas. Vous apprenez simplement à les bloquer, car vous venez de les enregistrer en tant que modèle général que vous pouvez facilement bloquer. Fonctionne pour moi pour les commentaires doc. Concernant le pliage, cela peut être fastidieux. Pour Java, mon Eclipse est configuré pour plier beaucoup de choses par défaut, car j'aime ouvrir mes fichiers Java et pouvoir les examiner comme des fichiers d'en-tête C (sans utiliser la vue d'ensemble). Et j'utilise Mylyn pour afficher uniquement les bits sur lesquels je travaille.
haylem
Oui, j'ai appris à les bloquer - avec un plugin, appelé bloqueur de publicités. Eclipse a une fonction de pliage, mais pas gedit, que j'utilise pour les petits programmes à fichier unique.
utilisateur inconnu
2

Voici un «anti-modèle» que j'ai trouvé tout au long du code de mon travail: l'utilisation des commentaires comme «journal des modifications»; c'est à cela que sert le journal de votre système de contrôle de version. Le code est jonché de choses comme:

// 05-24-2011 (John Doe): Changed this method to use Foo class instead of Bar

et inclut généralement l'ancien code qui a été commenté (encore une fois, c'est le but d'un système VCS, il n'a donc pas besoin d'être dans le code après l'écriture du nouveau code). Il faut également éviter les commentaires répétés comme "Pourquoi en avons-nous besoin?" ou pire encore, "Cela devrait probablement être renommé" (car il existe des outils sophistiqués pour renommer, donc dans le temps qu'il vous a fallu pour écrire ce commentaire, vous auriez pu renommer la chose). Encore une fois, je traite régulièrement ces deux commentaires, en suivant:

// (John Doe) 05-24-2011 not sure why we are using this object?
FooBar oFooBar = Quux.GetFooBar(iFooBarID, bSomeBool);
oFooBar.DiscombobulateBaz();

// (John Doe). This method is poorly named, it's used for more 
// than just frazzling arvadents
public int FrazzleArvadent(int iArvadentID)
Wayne Molina
la source
2
  1. Choisissez un système de documentation tel que doxygen et respectez-le. Continuez à vérifier les documents produits.
  2. Essayez d'imaginer quelqu'un de nouveau dans la base de code entrant et lisant vos documents, pourrait-il commencer à l'utiliser? Les stagiaires sont en fait bons pour cela, asseyez-en un nouveau avec votre base de documents existante et une tâche simple et voyez jusqu'où ils vont, s'ils trébuchent, bien sûr que tout ce que vous leur avez dit pour les remettre en marche va dans les documents.
  3. Faites des commentaires de documentation un point de contrôle dans vos processus de révision.
Kyrylo M
la source
1

Les lecteurs de code essaient généralement de répondre à trois questions:

  1. Que fait cette classe ou cette fonction? Si cela est difficile à répondre, cela fait trop. Un code difficile à documenter est généralement juste faux.
  2. Comment est-ce que je l'utilise? Un exemple peut être assez bon.
  3. Ce code est surprenant. Pourquoi fais-tu ça? Réponses les plus probables: contourner un bogue dans les composants tiers, car la technique évidente s'est avérée trop lente

Tout le reste doit être exprimé dans le code. Comme écrire de la prose, c'est un art et cela demande beaucoup de pratique. La seule façon de savoir si votre code est compréhensible est de demander à quelqu'un d'autre de le lire. Quand ils ne comprennent pas quelque chose, ne l'expliquez pas verbalement. Améliorez le code. Ajoutez des commentaires en dernier recours.

Si je vois "double longueur", je demanderai "Quelle est l'unité de mesure?" N'ajoutez pas de commentaire. Modifiez le nom de la variable. Si je vois un bloc de code et que je dis "qu'est-ce que cela fait?", N'ajoutez pas de commentaire. Extraire une fonction avec un nom significatif. Si vous ne pouvez pas extraire une fonction car elle aurait besoin de 17 arguments, alors refactorisez le code.

Kevin Cline
la source