Un bon code source est un code qui se lit SANS commentaires.
Par ce que s’il y a besoin de commentaires, c’est qu’il est difficile à lire…
Alors je sais, on t’a peut-être dit le contraire…
Traditionnellement, les commentaires sont un critère de code mieux documenté et donc, sous entendu, plus facile à maintenir.
Et si c’était tout l’inverse?
Pour paraphraser feu Nicolas Boileau:
Ce que l’on conçoit bien se design clairement, et le code pour le dire vient aisément.
En fait j’aurais même tendance à me méfier d’un code qui est commenté abondamment.
Alors oui, je sais, il y a des fois ou les commentaires sont utiles: sur les trucs légaux, ou les description d’API par exemple. Ok.
Je te parle en fait de la lisibilité de ton code.
Si tu as besoin de commentaires, es-tu certain que ton code se lit facilement?
Est-ce que l’INTENTION est claire?
C’est bien ce dernier point qui est important.
Je te donne un exemple: la constante magique.
N’as-tu jamais trouvé dans ton code une assignation du genre:
a = 42
A la simple lectures de cette ligne, tu es en droit de te demander quelle est l’intention derrière. Qu’avais donc le développeur dans la tête au moment où il écrit ça?
Un architecte aurait pu écrire. Ok je troll les architectes, tu verras pourquoi bientôt.
// la réponse vaut 42 car c’est la réponse universelle
a = 42
Un artisan développeur écrirait plutôt quelque chose comme:
const UNIVERSAL_ANSWER = 42
answer = UNIVERSAL_ANSWER
Tu vois le code est auto-descriptif!
En fait un code bien écrit dont l’intention est claire n’a pas besoin de commentaire. Par contre attention la réciproque n’est pas forcement vrai!
Et toi, est-ce que tu commentes ton code?
Si oui, dans quel objectif?
Qu’est-ce qui te pousse à le commenter?
Autre exemple plus concret celui-là:
Je dois modéliser l’état d’un attribut d’une classe.
J’ai l’option d’assigner une simple chaine de caractères:
state = “error”
Pas terrible: si je change la valeur de l’état, c’est non seulement toute la base que je vais devoir migrer, mais ça bon à la rigueur c’est normal, mais surtout tout le code dépendant de cet état.
Si je fais une faute de frappe, zou, une erreur silencieuse. Bon là normalement, tu as tes tests autos, mais imaginons que tu n’en n’ai pas…
Si, si, ça existe encore des projets sans tests automatiques…
Autre problème:
care.state = “error”
care.consistency = “error”
Là il faut se méfier: les deux valeurs ne renvoient pas au même type d’erreur…
À la place j’ai choisi de modéliser par un tableau de valeur constant.
STATE = [:ok => “ok”, :error => “error”]
CONSITENCY = [:ok => “ok”, :error => “error”, :monitoring => “monitoring”]
Du coup à l’usage, ça donne ça:
care.state = STATE[:error]
care.consistency = CONSITENCY[:error]
Ainsi je découple la valeur codée en base de la valeur réelle. Si demain je veux coder ça sur des entiers, je peux facilement.
A la lecture du code, c’est beaucoup plus clair sur le type d’erreur.
Après j’hésite à modéliser les valeurs des états sous forme de classe. Sauf que pour l’instant c’est vraiment qu’un attribut. Je n’ai pas de changement d’état…
Qu’en penses-tu?
Tu peux retrouver cet article en audio ici.
Un bon commentaire doit expliquer *pourquoi* on a écrit le code, pas ce que fait le code.
Vous l’expliquez bien : le code suffit à lui même pour comprendre ce qu’il fait.
Et un code propre, simple et clair n’a pas besoin de commentaires…
Sauf qu’en réalité, nous devons composer avec des contraintes qui empêchent de faire 100% propre.
Qui obligent d’utiliser des détournements, des choses pas logiques, pas simples. Parce qu’on n’a pas le choix.
Parce qu’au moment où on avait codé, telle API moderne n’existait pas encore.
Parce que telle dépendance était trop ancienne et incompatible, et son upgrade totalement hors sujet/budget/etc.
Parce que c’était un hotfix très urgent à finir en 5 minutes, et donc impossible de prendre 10x plus de temps pour faire propre.
Parce que… notre métier consiste à concilier la réalité avec la théorie.
Les commentaires doivent servir à raconter ça : pourquoi avons-nous dû coder ainsi.
Merci AxS pour ce retour.
Aurais-tu un exemple concret d’un bout de code à partager qui illustre ton point de vue?
#++
+1000.
Les commentaires sont indispensables pour capturer le « pourquoi ». Pourquoi cette approche parmi d’autres approches qui auraient pu être tout aussi valables ? Pourquoi cette partie du code est-elle nécessaire ? Ils servent aussi à donner la « big picture », la raison d’être d’un module ou d’une classe, et a préparer le lecteur, tout comme quand on aborde un livre on regarde le résumé en 4ème de couverture.
Et dire que les commentaires mentent alors que le code dit la vérité est juste faux. Le compilateur vérifie la syntaxe et les types, mais pas que les identifiants sont cohérents avec le code qu’ils nomment.
Je suis totalement d’accord avec les arguments et aux exemples données.
J’essaye d’ailleurs d’appliquer ces principes là le plus souvent possible.
Par contre, je suis du genre à mettre un commentaire en haut de la méthode pour que mes collègues ne soi pas obliger de lire le code de cette dernière( si par hasard j’aurais mal nommée la méthode et/ou paramètres ).
Après parfois les contraintes métiers un peu complexe, nous obliges parfois à commenter le code ou tenir un petit wiki à coter. Mais cela pour moi, doit être anecdotique.
Salut,
Tout à fait d’accord avec toi. La doc d’API reste utile.
Je suis plus gêné par les commentaires qui expliquent ce qui se passe dans le code. Je me pose toujours la question de comment l’exprimer directement par le code plutôt qu’un commentaire.
#++
200% d’accord :).
La doc c’est pour l’essentiel le « pourquoi c’est fait comme ça ».
On a tous lus ce commentaire parfaitement inutile :
// Je parcours les lignes
for l=1 to …
(même si en général le « parcours » n’est pas écrit comme ça. Ah l’orthographe et les informaticiens 😉
Par contre, on ne sait pas pourquoi on parcours ces lignes ;(
1ère chose super importante pour amener de la lisibilité : Le nom des variables, procédures, fonctions, classes, méthodes, …
Pourquoi a=42 si c’est l’âge ?
Age=42 ne serait-il pas mieux ?
Et puis, soyons dingues, préfixons !
C’est un entier ? => intAge=42
C’est un réel ? => reeAge=42
J’enseigne depuis peu la programmation à des étudiants en BTS. Les commentaires, j’en demande mais effectivement, le plus dur c’est d’expliquer et faire comprendre qu’il ne faut pas commenter le détail de chaque instruction mais plutôt une ligne de commentaire expliquant ce que fait une fonction, ou un commentaire en début de code contenant les révisions (quoiqu’avec les solutions GIT / SVN cette partie peut devenir obsolète si les modifs sont tracées et commentées).
Bref, un codeur sait lire le code, mais il perd du temps à comprendre pourquoi certains choix sont faits.
De cet article, je retiendrai surtout le mot « intention ». Car une des principales qualités d’un code bien écrit, c’est d’afficher clairement ses intentions.
Pour avoir travailler sur des projets non documentés et suffisamment vieux pour qu’aucun membre de l’équipe d’origine ne soient encore là pour l’expliquer, je peux témoigner comme on se sent démuni face à un code incompréhensible.
Et souvent les commentaires n’aident pas car ils finissent souvent par ne plus correspondre au code qui les suit ! Combien de développeurs relisent et corrigent les commentaires quand le code change ?
Comme je le dis souvent, les commentaires sont des mensonges en puissance…
Sylvain,
Je suis à 100% d’accord avec toi. Merci pour ton retour d’expérience !
#++
Benoit