Programmation : quand faut-il commenter son code ? Google s'invite dans le débat
Et montre que les commentaires peuvent très souvent être évités
Le 2017-07-19 11:43:08, par Michael Guilloux, Chroniqueur Actualités
En apprenant la programmation, votre professeur vous a certainement dit de toujours et bien commenter votre code. Rappelons que les commentaires sont des portions du code source ignorées par le compilateur ou l’interpréteur, car ils ne sont pas nécessaires à l’exécution du programme. Ils sont généralement insérés dans le code afin qu’il soit facile à comprendre et de sorte qu’on puisse le modifier facilement à l’avenir. Mais certains en font peut-être un peu trop avec les commentaires, en essayant de les placer à chaque petit coin du code ; une pratique qui est désapprouvée par beaucoup de développeurs expérimentés.
Pour ces derniers, si le code est tellement compliqué que cela doit être expliqué, il est presque toujours préférable d’améliorer le code que d’ajouter des commentaires. Dans un billet de blog datant de 2013, un développeur .NET du nom de Steve Smith a donc voulu trancher le débat en expliquant que « les commentaires doivent être généralement évités si le code peut dire ce qu’il fait. » Steve Smith pense en effet que « les bons commentaires disent ce que le code ne peut pas exprimer, comme pourquoi une technique particulière a été favorisée ou les dangers de l’optimisation d’un bloc de code. La plupart des autres types de commentaires sont simplement du bruit et leur présence encombre le code. »
Malgré tous les avis sur la question, la manière d’utiliser les commentaires reste une vieille question dans les habitudes de programmation. Google s’invite aujourd’hui dans le débat et montre qu’en réalité les commentaires peuvent très souvent être évités. « En lisant un code, souvent, il n'y a rien de plus utile qu'un commentaire bien placé. Cependant, les commentaires ne sont pas toujours bons. Parfois, le besoin d'un commentaire peut être un signe que le code devrait être refactorisé. Utilisez un commentaire lorsqu'il est impossible de faire en sorte que votre code s'explique par lui-même », expliquent Dori Reuveni et Kevin Bourrillion sur Google Testing Blog.
Si vous pensez avoir besoin d'un commentaire pour expliquer ce qu'est un code, ils proposent alors de procéder d'abord à l'une des opérations suivantes :
1. Introduire une variable explicative
Avec commentaire :
Sans commentaire :
2. Extraire une méthode
Avec commentaire :
Sans commentaire :
3. Utiliser un nom d'identificateur plus descriptif
Avec commentaire :
Sans commentaire :
4. Ajouter un contrôle dans le cas où votre code a des hypothèses
Avec commentaire :
Sans commentaire :
Il y a bien sûr des cas où un commentaire peut être utile. C'est le cas par exemple lorsqu'il est nécessaire de révéler votre intention, c'est-à-dire expliquer pourquoi le code fait quelque chose (ce qui est différent d'expliquer ce que fait le code). On peut, entre autres, également utiliser des commentaires pour apporter une clarification à une question qui a été soulevée lors de la revue du code ou que les lecteurs du code pourraient avoir. Dans tous les cas, les ingénieurs de Google pensent qu'il faut éviter les commentaires qui ne font que dire ce que fait le code, car ce n'est que du bruit. Par exemple :
Source : Google Testing Blog
Et vous ?
Qu’en pensez-vous ?
À quelle fréquence pensez-vous utiliser des commentaires ? Rarement, souvent, très souvent ?
Quelles règles observez-vous pour insérer des commentaires dans votre code ?
Voir aussi :
Un code bien écrit a-t-il besoin des commentaires ? Quelle est la place des commentaires dans votre code ?
Linus Torvalds fustige des développeurs du noyau Linux pour des styles de commentaires qu'il qualifie de « dégoûtants » et visuellement déséquilibrés
Pour ces derniers, si le code est tellement compliqué que cela doit être expliqué, il est presque toujours préférable d’améliorer le code que d’ajouter des commentaires. Dans un billet de blog datant de 2013, un développeur .NET du nom de Steve Smith a donc voulu trancher le débat en expliquant que « les commentaires doivent être généralement évités si le code peut dire ce qu’il fait. » Steve Smith pense en effet que « les bons commentaires disent ce que le code ne peut pas exprimer, comme pourquoi une technique particulière a été favorisée ou les dangers de l’optimisation d’un bloc de code. La plupart des autres types de commentaires sont simplement du bruit et leur présence encombre le code. »
Malgré tous les avis sur la question, la manière d’utiliser les commentaires reste une vieille question dans les habitudes de programmation. Google s’invite aujourd’hui dans le débat et montre qu’en réalité les commentaires peuvent très souvent être évités. « En lisant un code, souvent, il n'y a rien de plus utile qu'un commentaire bien placé. Cependant, les commentaires ne sont pas toujours bons. Parfois, le besoin d'un commentaire peut être un signe que le code devrait être refactorisé. Utilisez un commentaire lorsqu'il est impossible de faire en sorte que votre code s'explique par lui-même », expliquent Dori Reuveni et Kevin Bourrillion sur Google Testing Blog.
Si vous pensez avoir besoin d'un commentaire pour expliquer ce qu'est un code, ils proposent alors de procéder d'abord à l'une des opérations suivantes :
1. Introduire une variable explicative
Avec commentaire :
Code : |
1 2 3 | // Subtract discount from price. finalPrice = (numItems * itemPrice) - min(5, numItems) * itemPrice * 0.1; |
Code : |
1 2 3 4 | price = numItems * itemPrice; discount = min(5, numItems) * itemPrice * 0.1; finalPrice = price - discount; |
2. Extraire une méthode
Avec commentaire :
Code : |
1 2 | // Filter offensive words. for (String word : words) { ... } |
Code : |
filterOffensiveWords(words);
3. Utiliser un nom d'identificateur plus descriptif
Avec commentaire :
Code : |
int width = ...; // Width in pixels.
Code : |
int widthInPixels = ...;
4. Ajouter un contrôle dans le cas où votre code a des hypothèses
Avec commentaire :
Code : |
1 2 | // Safe since height is always > 0. return width / height; |
Code : |
1 2 | checkArgument(height > 0); return width / height; |
Il y a bien sûr des cas où un commentaire peut être utile. C'est le cas par exemple lorsqu'il est nécessaire de révéler votre intention, c'est-à-dire expliquer pourquoi le code fait quelque chose (ce qui est différent d'expliquer ce que fait le code). On peut, entre autres, également utiliser des commentaires pour apporter une clarification à une question qui a été soulevée lors de la revue du code ou que les lecteurs du code pourraient avoir. Dans tous les cas, les ingénieurs de Google pensent qu'il faut éviter les commentaires qui ne font que dire ce que fait le code, car ce n'est que du bruit. Par exemple :
Code : |
1 2 3 4 | // Get all users. userService.getAllUsers(); // Check if the name is empty. if (name.isEmpty()) { ... } |
Et vous ?
Voir aussi :
-
palnapMembre avertiEt vive les CheckStyles qui imposent de mettre des commentaires sur les getters & setters (et pire les langages qui imposent d'avoir des getters & setters
) et de lister tous les paramètres et retours des méthodes : Code Java : 1
2
3
4
5
6
7/** * Retourne l'âge du capitaine. * @return âge du capitaine **/ public int getAgeCapitaine() { return ageCapitaine; }
le 19/07/2017 à 12:10 -
BugFactoryMembre chevronnéUn autre conseil : penser à son public. Mon code est souvent lu par des stagiaires. Dans ce cas, le conseil d'éviter les commentaires évident n'est pas valable : pour un débutant, rien n'est évident. Je profite des commentaires pour signaler les designs pattern, etc. Ça évite qu'ils ne saccagent l'architecture pour résoudre un ticket.le 19/07/2017 à 13:55
-
transgohanExpert éminentJ'adore vos réactions tellement prévisibles...
Si c'est complexe c'est forcement que le code est bon à refactoriser...
Allez bosser sur des gros logiciels embarqués une fois dans votre vie et on en reparlera je pense.
Je ne vois pas comparer un webservice avec le système de guidage d'un missile ou bien le système de communication d'une navette spatiale.
Même correctement factorisé un logiciel de plusieurs centaine de millier de lignes reste en partie obscur dans la plupart de son fonctionnement au meilleur expert de la terre.
Pas le temps de potasser le tout qu'il y a déjà de nouvelles améliorations à apporter.le 19/07/2017 à 20:58 -
transgohanExpert éminentJe serai mitigé pour ma part...
J'aurai tendance à dire que mettre des commentaires partout est inutile mais à côté de cela je travaille sur du code très gros et très complexe et sans les commentaires inutiles cela devient une galère monstrueuse pour trouver rapidement ce que l'on cherche par simple méconnaissance du code concerné...le 19/07/2017 à 13:43 -
el_slapperExpert éminent séniorAllez, exemple vécu ce matin..... Bon, je dois écrire un script qui agit sur notre client lourd, et notamment rentrer le code 10 dans le type de transport. Alors j'avais ça :
Code : ActiveX("Transport").Type "10" + micTab
Code : 1
2'.ActiveX("Transport").Type "10" + micTab - ne marche pas, donne zéro .ActiveX("Transport").Type "9" + micDwn + micTab 'permet de taper 10, en fait
Dans ce genre de cas, le commentaire technique me parait indispensable - parceque la manière de faire qui permettrait de comprendre ne fonctionne pas(et je ne vais pas faire une usine à gaz pour remplacer les fonctions natives de UFT, juste pour ça). En tous cas celui de la deuxième ligne. Garder la première en code mort, ça m'emmerde, j'hésite, par contre. Ce n'est pas inutile(ça permet de voir facilement ce qu'on voulait faire), mais comme tout code mort, c'est moche, par définition.
Encore une fois, je ne commente pas le micDwn. Quelqu'un qui fait du UFT doit savoir ça, ou le retrouver facilement. Juste l'astuce horrible qui fait que le code est tordu pour un résultat qui paraissait simple à obtenir...le 18/08/2017 à 10:12 -
bcag2Membre actifG19 et G20 pages 318 et 319 de «Coder proprement» de Robert C.Martin (ISBN 978-2-7440-2583-9)
… rien de nouveaule 19/07/2017 à 12:19 -
PyramidevExpert éminentL'inconvénient des commentaires, c'est de risquer de ne pas être à jour par rapport au code.
En particulier, quand le code est mis à jour par des développeurs trop pressés, on peut se retrouver avec des absurdités du style :
Code : Sleep(3000); // Attendre 2 secondes.
Code : 1
2const DWORD durationMilliseconds = 3000; Sleep(durationMilliseconds);
Il est pertinent de créer une sous-fonction dans les deux cas suivants :
- La sous-fonction est appelée dans plusieurs fonctions différentes. On évite alors les copiés-collés.
- La fonction appelante devient trop grosse. Pour qu'on puisse la comprendre facilement de manière globale, il faut déplacer une partie de son code dans des sous-fonctions avec un nom parlant.
Cela dit, si une fonction de taille modeste contient un ou deux bouts de code que je souhaite commenter et que ces bouts de code n'existent pas ailleurs, je ne vais pas les transformer en sous-fonctions seulement pour éviter d'écrire des commentaires !
L'inconvénient de morceler en sous-fonctions, c'est qu'il faut faire des aller-retours dans le code si on veut voir l'implémentation de ces sous-fonctions.
Je suis d'accord.
Faire du défensif ne sert pas à éviter les commentaires, mais à détecter les erreurs à l'exécution.
Cependant, puisqu'une instruction telle que checkArgument(height > 0); indique déjà clairement la précondition de la fonction, il est inutile de rappeler en plus cette précondition sous la forme d'un commentaire.
J'écris des commentaires dans les cas suivants :
- Expliquer un choix, surtout s'il paraît étrange à un lecteur qui ne connaît pas le contexte.
- Résumer en quelques mots ce que fait une fonction ou ce que représente une classe, sauf si le nom de la fonction ou de la classe est déjà un résumé satisfaisant.
Le rôle du résumé est d'éviter d'obliger le lecteur à plonger dans le code s'il a besoin d'une information plus précise que le nom de la fonction ou de la classe mais pas forcément aussi précise que le code.
De même, il m'arrive parfois de résumer sous forme de commentaire ce que fait un bloc de code dans les cas où il n'est pas pertinent de déplacer ce bloc de code dans une sous-fonction (voir ci-avant). - Avertir sur les dangers d'une certaine fonction ou classe. Exemple : Attention, le bogue machin du ticket n°XXXX n'a pas encore été corrigé.
- Écrire parfois quelques "rappels" techniques si le lecteur a des chances de ne pas les avoir. Cela rejoint d'une certaine manière ce que disait BugFactory, mais ça ne s'applique pas qu'aux stagiaires. Cela s'applique aussi si on fait appel à des subtilités d'un langage ou d'une bibliothèque. Par exemple, en C++, il m'arrive d'écrire un commentaire du genre :
Code : 1
2
3
4// Rappel : propriétés de l'initialisation d'une variable locale statique : // - Si l'initialisation lance une exception, elle est considérée comme non faite et // sera retentée au prochain passage. // - L'initialisation est thread-safe depuis C++11.
- Mettre en évidence qu'un certain détail d'implémentation ne fait pas partie de l'interface.
Par exemple, dans une certaine classe, l'implémentation actuelle utilise un certain type de tableau associatif sous forme d'arbre binaire de recherche qui trie les éléments dans l'ordre des clés, mais l'implémentation future pourrait utiliser une table de hashage sans ce tri. Alors, dans l'interface de la classe, il vaut mieux avertir sous forme de commentaire : attention, ne vous reposez pas sur l'hypothèse que les éléments sont triés dans l'ordre des clés, car ça pourrait changer plus tard. - Aider l'utilisateur qui explore le code avec des commentaires de type "voir aussi telle fonction ou telle classe". Par exemple, quand il y a plusieurs fonction similaires (mais différentes), ce genre de commentaire aide l'utilisateur à trouver la bonne fonction à appeler.
Cela dit, comme je l'ai précisé, je suis conscient que, l'inconvénient des commentaires, c'est de risquer de ne pas être à jour par rapport au code. Du coup, quand une fonction a un code très simple et très petit, je préfère que la doc soit le code.
Par exemple, en C++, pour éviter d'écrire certaines préconditions et post-conditions sous forme de commentaires, il m'arrive de créer des fonctions en ligne qui ressemblent à :
Code : 1
2
3
4
5
6
7double my_sqrt(double param) { assert(param >= 0); double result = my_sqrt_impl(param); assert(result >= 0); return result; } // Rq : Dans du vrai code, je ne réimplémente pas sqrt, mais c'est pour l'exemple.
Code : 1
2
3bool invariant() const { // code qui retourne true si les invariants de la classe sont respectés }
le 19/07/2017 à 23:01 -
BouskRédacteur/ModérateurEt ? T'as jamais vu du code vieux de plusieurs dizaines d'années ? Tu peux aller voir ton patron et dire "bon mec, notre code il marche mais il a 30 ans, faut le changer, on est en 2017 !" ? Et il accepte et est prêt à changer un truc qui marche sans broncher parce que tu lui montres un livre ?
Bienvenue dans le monde réel.le 20/07/2017 à 13:41 -
Sange844Membre du ClubUne référence additionnelle à celles déjà citées:
Jeff Atwood: Code Tells You How, Comments Tell You Whyle 19/07/2017 à 13:54 -
Aurelien.Regat-BarrelExpert éminent séniorLes commentaires qui expliquent ce que font le code sont rarement une bonne chose. Mais sur du code complexe ou ancien (qui a été réécrit / optimisé / débogué plusieurs fois), ils sont très utiles pour clarifier le contexte ou l'historique du code,
en particulier expliquer ce que le code ne fait pas et pourquoi c'est ainsi.
Jetez juste un oeil au source de Linux ou Chromium pour vous convaincre.le 19/07/2017 à 14:05