web-dev-qa-db-fra.com

Style et recommandations de commenter le code

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 /* */ 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 d'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 de 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.

27
Kyrylo M

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 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 langues 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 les avis de droit d'auteur - c'est historique pour moi et vient de mon parcours éducatif. Malheureusement, la plupart des IDE bousillent quand on utilise auto -format):

/*
** 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. Dans un cas de retour très spécial, par exemple, ou pour documenter les instructions switch d'un case (rare, je n'utilise pas souvent de commutateur), ou lorsque je documente des branches dans un if ... else contrôler le flux. Si ce n'est pas l'un d'entre eux, 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 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 catch "forcé":

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 utilisais 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 un jour améliorer cela, je serais beaucoup plus heureux cependant.

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. (Lire ma réponse à cette question sur "commentaires en ligne et 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/les 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 Literate Programming

Vous voudrez peut-être vous intéresser à Literate Programming , comme présenté dans ce article de 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 remarque et d'exemple: Le nderscore.js framework JavaScript, nonobstant la non-conformité avec mon style de commentaire, est un assez bon exemple d'un bon document codebase et une forme bien source annotée - mais peut-être pas la meilleure à utiliser comme 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 cohabiter bien. Cela fait partie de votre style, et vous devriez trouver la fine ligne entre développer un style de codage qui vous définit comme un codeur (ou comme un adepte d'une école de pensée ou d'organisation avec laquelle vous avez une connexion) et respectant la convention d'un groupe pour la cohérence .

17
haylem

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 élément 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 devraient avoir des commentaires d'en-tête bien écrits pour la documentation.

16
Bronumski

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 apply(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 travaillent 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.

5
mattnz

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.

4
Dave
  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 vraiment 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.
2
Kyrylo M

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 nouvelles lignes).

2
Kyrylo M

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.

2
user unknown

La recommandation la plus importante est:
Commentez l'inattendu, pas l'évident!

Un commentaire comme celui-ci est inutile:

// Adds a to b and write the result to c
c = a + b;

Il répète simplement ce que dit le code et vous ne devriez pas écrire de commentaires pour les gens qui ne comprennent pas le code comme s'ils ne comprenaient pas le code, ils ne liraient aucun code et s'ils ne lisent aucun code, ils ont gagné 'lisez pas vos commentaires non plus. Gardez à l'esprit que vous écrivez des commentaires principalement pour d'autres personnes capables de comprendre le code aussi bien que vous le comprenez.

Ainsi, la plupart du code ne devrait pas du tout nécessiter de commentaires car si la plupart de votre code est si maladroit qu'il ne peut pas être compris sans commentaires, quelque chose ne va pas avec le code ou votre style de codage. Les commentaires doivent être l'exception et non la règle, ce qui signifie que le style de vos commentaires est loin d'être aussi important que votre style de code.

Lorsque vous placez des commentaires dans votre code pour commenter les non-obivous, je recommande de les garder simples, courts et directs. Ce genre de compliments n'a même pas besoin d'être des phrases grammaticalement correctes ou d'utiliser la ponctuation. Ils sont comme du code supplémentaire, pas seulement pour le compilateur mais pour les êtres humains.

// Setting owners must happen on main thread
// and this function must not block
if (!info->owner) return errMissingOwner;

Comment est-ce un bon commentaire? Un programmeur qui lit le code peut se demander " S'il n'y a pas de propriétaire, pourquoi ne pas simplement en définir un au lieu de renvoyer une erreur? " Le commentaire donne la réponse : Parce que cela doit se produire sur le thread principal et cette instruction seule implique que la fonction ne s'exécute probablement pas sur le thread principal. D'accord mais alors un programmeur peut se demander " Pourquoi ne pas simplement envoyer au thread principal? " et le commentaire donne la réponse: la fonction ne doit pas bloquer et vous ne pouvez pas garantir qu'il ne bloquera pas à moins que vous sachiez avec certitude ce que le thread principal fait actuellement. Le commentaire répond donc à toutes les questions auxquelles le code seul ne peut répondre et aucune de ces réponses n'est évidente. Grâce au commentaire, le lecteur saura pourquoi échouer avec une erreur est la seule option significative ici et il aide également les futurs programmeurs qui veulent toucher le code à ne pas faire une erreur stupide.

Pourtant, les vrais commentaires importants sont des commentaires à des fins de documentation. Si quelqu'un ne connaît que votre interface mais pas l'implémentation, les commentaires sont la seule source d'informations supplémentaires sur la façon d'utiliser correctement votre code et sur le comportement à attendre. Ces commentaires doivent être bien lisibles, généralement des phrases entières, et utiliser une grammaire et une ponctuation correctes.

/// Sorts an integer array in place. 
/// The sorting algorithm is stable.
/// Sorting takes O(n * log2(n)) time 
/// and at most (n / 4) * sizeof(int) memory.
///
/// @param array The array to be sorted.
/// @param count Number of elements in the array.
///
/// @return @c false if memory allocation failed and
/// the array wasn't touched, @c true otherwise.
///
bool sortIntArray ( int * array, size_t count );

Sans ce commentaire, un programmeur peut deviner ce que fait la fonction et ce que signifient les paramètres, mais il est impossible de savoir si le tri est stable, quelles limites de temps ou de mémoire il aura, ou pour quelle raison l'opération pourrait échouer et ce que l'exact conséquence de l'échec sera.

2
Mecki

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)
2
Wayne Molina

Une réponse quelque peu étrange mais, le meilleur type de commentaires est * aucun commentaire * .

Si votre code est clair, propre et honnête:

Vous n'avez [~ # ~] pas [~ # ~] besoin de commentaires.

Les commentaires mentent et sont difficiles à maintenir. (l'un des nombreux liens sur Google qui en parle)

Essayez de nommer votre méthode pour suggérer l'intention, respectez le principe de responsabilité unique chaque fois que possible et votre code lira comme un jeu d'enfant sans avoir besoin de commentaires embêtants.

(Voir réponse de bronumski pour quelques exemples de code)

1
JeromeJ

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.

1
kevin cline