Sujet qui fait suite à
celui-ci. C'est bien, en 3 jours on a 2 articles sur 2 sujets similaires mais complémentaires. L'un sur l'utilité des commentaires, l'autre sur l'utilité de la documentation, les deux par rapport au code. De quoi prendre le temps d'expliquer les différences. J'ai donné
mon avis pour la comparaison code-commentaire, voilà donc celui pour la comparaison code-documentation.
L'ennui est que la traduction de la source laisse à désirer et, du coup, il y a des choses qui portent à confusion. Je vais donc d'abord commenter l'article DVP de manière isolée, et ensuite la source elle-même.
L'article DVPOn construit ici sur des termes communs mais utilisés de manière non commune. En l'occurrence, je suis tout à fait d'accord avec ceci :
Envoyé par
Patrick Ruiz
[un commentaire] est destiné à « documenter le pourquoi et non le comment », c’est-à-dire à : expliquer de précédentes approches qui n’ont pas fonctionné, faire apparaître de possibles améliorations, expliquer les compromis dans l’implémentation en cours, etc.
mais pas avec cela :
Envoyé par
Patrick Ruiz
Ce sous-ensemble est à mettre en cohabitation avec les conventions de nommage et de programmation structurée au sein du code. Ces dernières viendraient ainsi jouer leur rôle qui est – selon lui – de « documenter le comment et non le pourquoi ».
Autrement dit, on parle de la structure du code comme d'une documentation, alors qu'en général on parle de documentation pour parler de textes autres que le code. On introduit donc un amalgame entre le code et la documentation, qui amène à une incohérence notoire : dès lors que la structure du code est en elle-même de la documentation, un code ayant toujours une certaine structure, il est par définition toujours documenté, et donc autodescriptif au moins dans une certaine mesure. On ne peut donc pas parler de mythe de l'autodescriptif, ça n'a pas de sens.
Je note par ailleurs que la critique cible les arguments parlant du
fonctionnement de la fonction :
Envoyé par
Patrick Ruiz
Il semblerait cependant que certains programmeurs fassent fi de ce jeu de rôle et se limitent uniquement au respect des conventions de nommage et de programmation structurée pour affirmer que leur code source est « autodescriptif ». « Je n’ai plus besoin d’expliquer quoi que ce soit puisqu’il est désormais évident que le fonctionnement du programme est accessible à tous », leur attribue-t-il alors.
Et ils ont raison ! En effet, on peut séparer une tâche en trois phases :
1. L'occurrence d'un
contexte (Quand)
2. qu'on transforme au travers d'un
moyen (Comment)
3. pour atteindre un
objectif (Pourquoi)
Le code concerne uniquement le
moyen. Il décrit
comment passer du contexte à l'objectif. S'il est autodescriptif, cela veut dire qu'en connaissant le contexte et l'objectif, lire le code suffit à comprendre le moyen utilisé pour passer de l'un à l'autre. Un code qui n'est pas autodescriptif nécessite une description supplémentaire pour comprendre ce moyen, typiquement en annotant le code au fur et à mesure de son déroulement. Ces annotations, qui sont donc par définition
facultatives car réécrivant le code dans un autre langage sans rien changer audit code, sont ce qu'on appelle des
commentaires. Code comme commentaires concernent donc le
moyen, et uniquement celui-ci.
Pour le reste, à savoir le
contexte d'utilisation et l'
objectif visé par la fonction, il s'agit de la
documentation, dans un sens plus usuel que celui utilisé dans l'article, à savoir une description à destination des
utilisateurs de la fonction. Elle permet de décider de la pertinence de la fonction pour le contexte auquel on fait face et l'objectif qu'on souhaite atteindre. Lire la documentation doit suffire pour juger la
pertinence de la fonction, indépendamment de son fonctionnement.
Or, ce que l'article critique, c'est que non, il ne suffit pas d'avoir le code pour comprendre le fonctionnement. Mais ce fonctionnement est décrit par le code et ses commentaires, pas par la documentation de la fonction (au sens usuel du terme, pas au sens ambiguë de l'article) qui elle se concentre sur les contextes d'application et les objectifs. Donc pour comprendre le fonctionnement, il faut avoir le code et les commentaires. Sauf que voilà, l'article précise bien que les commentaires ne doivent concerner que "le pourquoi et non le comment", ce qui revient à dire qu'on ne parle en fait pas du fonctionnement dans ces commentaires. Je suis tout à fait d'accord sur ce dernier point : si le code est bien fait, nul besoin de se répéter au travers de commentaires. Mais si on en vient là, alors le fonctionnement n'est décrit, au final, que par le code source. Et c'est là où le raisonnement tombe, parce que l'article amalgame documentation et code :
Envoyé par
Patrick Ruiz
« Décider que les noms de variables [la convention de nommage] constituent la seule documentation requise signifie que seules les personnes qui lisent le code source peuvent en faire usage », déclare Eric Holscher pour s’indigner du fait que la documentation s’adresse en principe aux « utilisateurs de tous bords ».
Chercher à comprendre le
fonctionnement de la fonction n'a aucun intérêt pour un
utilisateur, qui veut avant tout connaître les
contextes d'utilisation et ce que permet la fonction, autrement dit ses
objectifs. Lire le code n'a donc aucun intérêt pour un
utilisateur, dès lors que la
documentation (au sens usuel) est bien faite. Mais comme on confond ici
documentation et
code (notamment les conventions de nommage), on amalgame tout naturellement
usage et
fonctionnement. Et c'est là l'erreur. En l'occurrence :
Envoyé par
Patrick Ruiz
Eric Holscher met ainsi de l’emphase sur le fait que la documentation du code va bien au-delà de la mise en œuvre du tandem de règles précédemment mentionné. Se limiter à respecter ces règles conduirait fatalement à exclure les personnes sans compétences en programmation de la liste des potentiels utilisateurs.
Non, car les personnes aux compétences limitées (on ne va pas dire sans, sinon elles n'ont rien à faire là) ne sont en effet que de simples utilisateurs, et n'ont donc aucun intérêt à lire le
code (et ses commentaires éventuels). Seule la
documentation (au sens usuel) doit les intéresser.
Oui, la documentation s'adresse aux utilisateurs de tous bords. Mais oui, aussi, le code seul permet de comprendre le fonctionnement (s'il est bien fait). L'erreur se situe sur l'amalgame entre fonctionnement et usage, favorisé par l'amalgame entre code et documentation.
Mais ce n'est pas la seule erreur. On en a une autre de taille : l'amalgame entre profession et formation, ou code de production et code de présentation. Si on prend 2 fonctions traitant le même contenu, mais dans des contextes ou à des fins différentes, se serait une erreur de débutant que de les utiliser toutes les deux de la même manière. Erreur d'autant plus favorisée que les deux fonctions ont le même nom. Pour autant, cela resterait bel et bien deux fonctions différentes à utiliser différemment. C'est pourtant l'erreur de l'article ici : partant du principe qu'on a du code, on amalgame le code utilisé dans un contexte de production et celui utilisé dans un contexte de formation. Cela se sent déjà quand on parle de "personnes sans compétences en programmation", mais d'autant plus quand on parle de tutoriels :
Envoyé par
Patrick Ruiz
Il y a donc plus à faire que mettre côte à côte la « documentation du pourquoi et non du comment » et celle du « comment et non du pourquoi ». Il faudrait en plus penser à l’intégration d’éléments comme les tutoriels susceptibles de booster l’utilisabilité du logiciel ou de l’application déployée.
Ces tutos, ou codes de présentation, visent à illustrer l'utilisation du code de prod. Ils peuvent être extraits du code de prod, mais ce n'est pas nécessaire. Le fait qu'ils le soient permet d'avoir une formation dédiée au projet, plutôt que quelque chose de plus générique, mais comme les exemples utilisés ne concerneront que quelques cas, il faudra forcément savoir généraliser pour pouvoir traiter le reste de l'application. C'est donc un plus, mais pas une nécessité.
La vrai nécessité est que ces codes de présentation, à contrario du code de prod, sont destinés à être lus par des gens qui n'ont
pas forcément les compétences suffisantes pour comprendre le code, à contrario du code de prod qui est censé être géré par des gens qui ont
au moins ces compétences. C'est de par cette différence d'objectif que les codes de présentation doivent être
commentés (et non documentés). Partir du principe que le code de prod doit être commenté comme un code de présentation ne se justifie que si on accepte que des gens incompétents mettent les mains dans le code, ce qui est de toute évidence incohérent. C'est partir du principe qu'un projet Open Source sur GitHub par exemple ne devrait pas avoir de site Web dédié illustrant l'usage du code, le code du projet devant être lui-même commenté pour que les "incompétents" puissent s'y retrouver. C'est viser à côté en se donnant un boulot supplémentaire inutile. Il vaudra mieux avoir des codes de présentation dédiés illustrant les cas intéressants de manière succincte, plutôt que de commenter l'intégralité du projet en se disant que n'importe quel bout de code puisse être lu (et jugé) par un incompétent.
Donc encore une fois, oui à :
Envoyé par
Patrick Ruiz
« Si vous tenez à avoir des utilisateurs pour les œuvres que vous produisez, il va falloir rédiger de la documentation », a-t-il conclu.
mais on enfonce des portes ouvertes car ces critiques se basent sur des amalgames.
L'article sourceL'article source, quant à lui, est différent. En l'occurrence, on ne parle pas de code "autodescriptif" mais "auto-documenté" (self-documenting), ce qui est une différence de taille : on parle bien d'un code qui, de par lui-même, fournit la documentation. Dans la partie précédente, j'explique que le code et la documentation sont tous les deux nécessaires car strictement complémentaires, avec le code pour décrire le moyen et la documentation le contexte et l'objectif. Parler d'un code comme auto-documenté est donc, selon
mes définitions, effectivement un mythe. La question est de savoir si l'auteur utilise les même. Hélas, ce n'est pas le cas, l'article mentionnant dès le départ qu'il amalgame documentation et commentaires :
This view generally conflates documentation with code comments.
Néanmoins, l'auteur restreint l'usage de commentaires à un but spécifique* :
Code comments document the why, not the how.
Les commentaires dont il parle sont à prendre comme des descriptions de
pourquoi tel code a été choisi, et non une simple traduction du code en langage naturel (
comment). Je suis tout à fait d'accord sur cette restriction, cependant ce doit être un cas qui arrive rarement : la fonction elle-même dispose normalement d'une documentation (au sens usuel) qui détaille justement le contexte et les objectifs de la fonction. De là, si le code reste clair et bien organisé (et donc relativement court grâce à l'usage de sous-fonctions bien nommées et elle-même documentées), ce genre de commentaires devrait être particulièrement rare, ne concernant que des bouts de code très optimisés pour exploiter au mieux des subtilités du contexte. Cependant, l'auteur n'est pas aussi restrictif quant à ses exemples :
- Explaining previous approaches that didn’t work
- Presenting an example usage of the function and example output
- Explaining trade offs in the current implementation
- Marking possible improvements (TODOs) in the code
- Anything else you’d like to communicate with someone reading or developing the code
- OK, mais plutôt que donner les cas précédents qui n'ont pas fonctionner, donner uniquement les contraintes déduites de ces erreurs.
- Un exemple d'utilisation par exemple ne répond à aucun pourquoi, donc ça n'a rien à faire là. C'est de l'ordre du code de présentation, voire de la documentation, et non du commentaire. Mais comme il amalgame documentation et commentaire, ce n'est pas complètement incohérent au premier abord, mais au final ça montre bien qu'on ne sait pas tout à fait sur quel pied dancer.
- Leçon tirée, donc oui.
- Je ne traite pas les TODO comme de simples commentaires car ils s'exploitent dans le processus de développement. J'ignore donc ce point là.
- Complètement faux : tout commentaire est écrit parce qu'on estime que ça peut être utile. On ne peut pas commencer par dire qu'un commentaire se limite à tel type de contenu pour ensuite dire qu'on peut y mettre tout ce qu'on veut. L'auteur n'est ici pas cohérent.
On voit donc que l'auteur ne maîtrise pas tout à fait ses propres recommandations. L'amalgame documentation/commentaire y a d'ailleurs son impact.
Il annonce aussi que* :
Object names document the how, not the why.
Oui, mais ce ne sont pas les seuls : les noms des objets, les noms de méthodes, mais aussi la structure du code elle-même décrit le comment. C'est le code dans son intégralité qui, parce qu'il utilise tels termes de telle manière, décrit le fonctionnement du processus implémenté.
Tout de suite après, il affirme que :
[Code comments and object names] are effectively inverses of each other.
Si on s'en tient à ses deux affirmations, c'est logique, mais on a vu que ses définitions laissent à désirer niveau rigueur. Cependant, si on s'acquitte de son amalgame entre documentation et commentaires, et qu'on étend la deuxième affirmation à l'ensemble du code, on peut reformuler ainsi :
[Documentation and code] are effectively inverses of each other.
et là je tombe entièrement d'accord, car la documentation explique le contexte et le pourquoi, alors que le code décrit le comment, les deux étant strictement complémentaires et nécessaires. On pourrait dire qu'ils sont aussi suffisants d'un point de vue formel (i.e. pas besoin de plus pour créer les tests en théorie), mais il sera facile de trouver d'autres choses utiles à y ajouter pour des raisons pratiques (e.g. les tutos).
Donc, si on corrige au fur et à mesure, je peut tomber d'accord, l'ennui étant qu'il continue de construire sur son amalgame :
An argument against comments is an argument against communication.
Je suis d'accord quand on parle de documentation au sens usuel, mais pas de commentaires. En l'occurrence :
Once you start writing quality code
comments, you can use a tool like
Sphinx or
Javadoc to include them in your documentation.
On parle là d'outils générant de la documentation au sens usuel, à savoir du texte
sans code (HTML, LaTeX, plain text, etc.). Or, un commentaire au sens usuel (à l'intérieur d'une implémentation) est normalement associé à un bout de code au sein d'une fonction, pas à la fonction entière, et n'a donc aucun sens sans le code associé. Cela vient donc contredire les exemples donnés par l'auteur, qui parle de commentaires utiles pour celui qui lit ou change le code : sans le code auquel il se rattache, le commentaire n'a plus beaucoup de sens. On parle donc bien de faire de la documentation, et non des commentaires. Encore une fois, l'amalgame ici n'est pas justifié, et au contraire introduit une confusion, voire une erreur, quant à l'usage des outils cités. Oui c'est juste si on parle de documentation, mais pas avec des commentaires.
Le pire est qu'il ne reste même pas constant sur son amalgame, car dans sa seconde section il titre :
Documentation is more than code comments
Désormais, on n'amalgame plus les deux. Les commentaires sont un type particulier de documentation seulement. Donc si avant on parlait de commentaires, on ne parlait pas de la documentation dans son ensemble ? Sauf que du coup, les points où ça faisait sens quant on interprétait "comments" comme "documentation" ne sont même plus possibles. On détruit à petit feu les fondations, pourtant déjà bancales, sur lesquelles s'appuyait le raisonnement tenu jusque là...
Il poursuit :
Documentation is for every possible user.
Oui la documentation (au sens usuel) est faite pour toute usager potentiel, mais un commentaire dans du code n'est fait que pour le codeur qui ira juger/modifier le code (le comment), et non le simple usager (qui se concentre sur quand et pourquoi l'utiliser).
I have a few rhetorical questions about this philosophy:
- Where does the tutorial go in your self-documenting code?
- How do you put installation instructions in your variable names?
- How many users does your self-documenting code have?
C'est là que le second amalgame est fait, entre code de production et code de présentation :
- Le tuto n'a rien à faire dans un code de production. Ça a un rôle d'introduction et de formation, et donc doit se trouver à part pour être utiliser avant de mettre le nez dans le code de prod.
- Les instructions d'installation n'ont encore une fois rien à voir. Il s'agit de l'usage de la lib, ce qui se place dans la documentation de celle-ci, et non pas dans la documentation d'une fonction et encore moins dans des commentaires. Critiquer les noms de variables n'a donc aucun sens, car leur ajouter un commentaire ou même une doc ne résoudra pas le problème non plus.
- Là, on touche avant tout à l'ego du codeur, la question étant juste hors sujet. Il s'agit de connaître les types d'utilisateurs pour établir la documentation en conséquence, mais là on peut prendre 2 perspectives : les utilisateurs potentiels et les utilisateurs ciblés. Dans le premier cas, l'ennui est que ça peut être n'importe qui, donc on pourra faire tout ce qu'on veut, on pourra toujours trouver des exemples d'utilisateurs non satisfaits par la doc fournie, c'est donc un cas d'idéalisme prononcé. Le second cas, par contre, c'est au responsable du code de le décider : il n'a pas à se sentir coupable si certains utilisateurs potentiels ne sont pas couverts, tout simplement parce qu'il ne l'a pas prévu comme cela. D'autres pourront éventuellement aider pour compléter, mais certainement pas lui reprocher de ne pas couvrir tel ou tel type d'utilisateur. Tout du moins, pas sans lui faire admettre que ça serait utile et l'aider à obtenir les moyens de le faire (i.e. participer).
En bref, l'auteur a quelques idées tirées de bonne pratique, mais n'a à mon sens pas encore la compréhension nécessaire pour en faire un tout cohérent, car s'appuie sur des amalgames en générant d'autres, inutiles voire problématiques.
* Je déplore qu'il parle de documenter (anglais : documents) plutôt que de décrire (anglais : describes), car ça favorise l'amalgame documentation/commentaire qui au final aurait très bien pu être évité.
Les réponses du fil
Envoyé par
koyosama
J'etais jeune et je croyais aussi que le code commente ou la documentation ne servait a rien.
Je vais entendre dans ce post, les trucs classqiues :
- Pas le temps de commente le code ou faire de la documentation
- Pas besoin de commenter, le code est lisible
- Il faut poser plus de questions
- Mauvaises excuse, ce n'est pas qu'on n'a pas le temps, mais qu'on a décidé de consommer le temps sur la quantité plutôt que la qualité.
- Ça c'est juste, tant que ça reste honnête : c'est parce qu'on a pris le temps de faire un code lisible que les commentaires deviennent superflus. La documentation par contre est toujours nécessaire, ne pas la confondre avec les commentaires comme le fait Holscher, sinon on n'y arrive plus.
- Hors sujet : on parle de nouveaux internes, pas d'utilisateurs externes, or c'est là le sujet de l'article.
Envoyé par
martopioche
En fait pas du tout, elle fait exactement la distinction entre les différents niveaux : nommage, commentaires, documentation type JavaDoc, PyDoc, DocBocks…, tutos… C'est bien écris dans son post mais très mal rapporté…
Non, l'auteur d'origine parle des différents niveaux mais les mets effectivement ensemble. Ce n'est pas juste mal rapporté sur DVP, c'est l'article d'origine qui mélange tout dès le départ. Pour les commentaires et la doc, il le dit même explicitement dès les premières ligne. Pour les tutos, il fait comprendre qu'il faut bien les intégrer quelque part, or avec un post qui se concentre sur "il faut de la doc", tu en tires qu'il faut mettre les tutos dans la doc. Il confond tout.
Envoyé par
martopioche
Mon dernier exemple : écrire un programme qui demande l'âge du capitaine et l'affiche, mais indique que ce n'est pas possible si il est mineur ou à la retraite SAUF si la question est posée entre 1939 et 1945 où on suppose qu'il peut être mobilisé…
En Java ça te va ?
[spoiler]
Sur la seule base de ce que tu donnes, un design fiable est une classe abstraite qui utilise une API spécifique à son traitement. L'implémentation des cette API nécessite un échange constructif pour préciser les termes et choisir les références à exploiter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
public abstract class MartopiocheChallenge implements Runnable {
@Override
public void run() {
AgeCapitaine age = demanderAgeCapitaine();
if (entre1939et1945()) {
afficher(age);
} else {
if (age.deMineur()) {
throw new RuntimeException("Impossible, il est mineur.");
} else if (age.deRetraité()) {
throw new RuntimeException("Impossible, il est retraité.");
} else {
afficher(age);
}
}
}
public static interface AgeCapitaine {
boolean entreAnnées(int année1, int année2);
boolean deMineur();
boolean deRetraité();
}
protected abstract AgeCapitaine demanderAgeCapitaine();
protected abstract boolean entre1939et1945();
protected abstract void afficher(AgeCapitaine age);
} |
[/spoiler]
Envoyé par
cedric57
Moi perso dans la plupart des cas…je comprendrai plus vite le code en le faisant fonctionner avec un débogueur ou encore en ajoutant des messages de log.
Voilà l'exemple type du gars qui se plante lamentablement à l'examen d'info : manque de bol, le script formate ton disque. Il aurait peut-être fallu le comprendre
avant de l'exécuter.
5 |
0 |