Clean Code : le Bon Codeur et le Mauvais Codeur

Au jour le jour, nous – les développeurs – passons notre temps à geindre :

  • « C’est quoi ça !?? »
  • « Pourquoi il a fait ça comme ça ?!!???? »
  • « Je comprend rien à ce bout de code »
  • « ### !1%%$$$££ !!! »
  • « Ca, c’est encore du code à Michel* !! »

J’ai donc décidé de passer du temps à essayer de comprendre pourquoi on en arrive à cet état et comment faire pour ne plus être aigri au travail… Je suis tombé sur l’ouvrage d’Oncle Bob, « Clean Code », dans lequel il dit justement :

« The ratio of time spent reading (code) versus writing is well over 10 to 1… (therefore) making it easy to read makes it easier to write. »

Je me suis rendu compte que notre problème n’est pas tant un manque de connaissances ou de skills (quoi que…) mais davantage un manque de communication : nous écrivons du code « opérationnel » au lieu d’écrire du code destiné à être lu et compris par des humains (pas seulement des codeurs).

En lisant plusieurs ouvrages sur le sujet j’ai été déçu… et surpris : déçu, car je m’attendais à des techniques de ninja de super haut niveau pour devenir un killer, mais j’ai constaté que la majorité des axes d’amélioration était simple à comprendre et tenait plus du bon sens que du réel savoir-faire des développeurs.

Je vous propose donc une série d’articles dans lesquels je vais partager avec vous mes découvertes pleines de bon sens et accessibles à tout développeur.

L’idée étant de vous montrer qu’en gardant à l’esprit que l’on écrit du code pour des développeurs et non pas pour des machines et en mettant en œuvre des pratiques simples, votre code sera positivement impacté, pour un investissement très limité, voire nul en temps de refactoring et en expertise nécessaire.

Pour ce premier blog-post, et comme son nom l’indique, je vous propose de discuter du nommage des variables.

Pour cela, je vous propose un extrait d’un livre :

« n=nuit ; n2=nappe ; s=sale ; I = Augustin ;A2=assiette ; F=fourchette ; _vi = vin ; R;

…n, lentement, était tombée ; un jour s, d’un gris de cendre, s’épaississait derrière les R. Quand I posa deux lampes allumées, une à chaque bout de la table, la débandade du couvert apparut sous la vive clarté, les a2 et les f grasses, la n2 tachée de _vi, … » (Extrait de l’assommoir de Zola)

Inutile de vous dire que cela est illisible et inacceptable ! Si l’auteur de ces lignes avait pris ce genre de conventions – certes économiques en termes de nombre de caractères – personne n’aurait jamais acheté ses ouvrages. Ne nous attardons pas dessus car nous sommes tous d’accord pour dire que cela n’est pas possible : c’est du bon sens.

Projetons cet exemple sur du code

Le Mauvais Codeur :

image

On comprend le code : c’est un tri de tableau (qui représente quoi ? ) en fonction de la valeur (qui représente quoi ?) stockée en index 4 (pourquoi 4 ?) et qui doit être égale à 6 (pourquoi ?).

Bref, on a là un bout de programme simple mais incompréhensible : nous sommes sur une abstraction algorithmique simple qui doit être contextualisée pour pouvoir saisir l’intention fonctionnelle.

Le Bon Codeur :

Maintenant, prenons quelques secondes pour améliorer le nom des variables en utilisant des noms plus explicites.

SelectCells

Nous avons ici uniquement remplacé les noms des variables sans avoir modifié la structure du code et les choses sont déjà plus claires. L’intention fonctionnelle est explicitée : on trie un plateau en sélectionnant les cellules sélectionnées. De plus, utiliser des noms explicites oblige à réfléchir à ce que l’on fait. Nous avons souvent l’habitude de réutiliser nos variables pour deux intentions différentes. Par exemple, avec une string que l’on utilise pour mettre en forme l’id d’un utilisateur et isoler ses initiales, utiliser deux variables clairement nommées vous évitera de coupler les fonctionnalités et donc les effets de bord.

Ici, il est également important d’utiliser des termes compréhensibles par tous les acteurs, en DDD (Domain Driven Design) on parle de langage explicite propre au domaine métier pour être sûr que lorsque l’on parle de gameBoard tout le monde (dev, QA, chefs de projets, BA, PO,…) comprennent la même chose.

Bien sûr, le code obtenu ici n’est pas “clean”…mais cela fera l’objet d’autre blog post 🙂

La notation Hongroise:

Il ne faut pas tomber dans l’exces inverse et vouloir mettre trop d’informations dans le nommage des variables comme avec la (encore trop utilisée) notation Hongroise. Le principe est de normaliser les préfixes des variables pour indiquer leurs type ou leur utilisation. On aura, par exemple:

  • si nom est une variable de type string : sNom
  • si age est de type int : iAge

le plus drôle étant lorsque l’on utilise des tableaux. Si ages est un tableau d’entiers, on va alors avoir: aiAge (Array + Int)

Sans mettre des exemples avec des types complexes (delegate, pointeurs…) on se rend tout de suite compte que la lisibilité baisse avec ce genre de norme.

En C#:

En général, on recommande d’utiliser la casse Camel (Camel Case) : qui consiste à écrire un ensemble de mots en mettant en majuscule la première lettre des mots liés.

On distingue 2 variantes:

  • la Lower Camel Case qui consiste à laisser en minuscule la première lettre du premier mot comme par exemple: lowerCamelCase. On utilise cette notation pour les variables (fields) et les paramètres de fonctions. Parfois, vous verrez un “_” devant les fields privés pour les distinguer des paramètres de fonctons… mais je ne suis pas fan car à mon sens c’est de la notation Hongroise : on préfixe avec un symbole qui donne une information sur l’utilisation de notre variable.
  • la Upper Camel Case qui met toute les premières lettres en majuscule comme par exemple: UpperCamelCase. Celle-ci est utilisé pour les classes, les méthodes, les propriétés, les variables publiques, les interfaces, les structures…

Pour conclure

Nous ne sommes plus dans les années 60, où la place mémoire était un enjeu et nous obligeait à écrire du code compact et utilisions des éditeurs incapable de nous donner des informations sur notre code (comme le type des variables). Nous avons largement la place pour utiliser des noms de variables clairs et compréhensibles par un humain. Cela ne coûte pas plus cher en temps et en compétences et cela améliore directement la qualité de notre code… Vous n’avez donc plus de raisons pour ne pas le faire !

Bien évidement, là encore, le code obtenu n’est pas parfait et peut encore être amélioré… mais nous verrons cela dans un prochain article.

*Toutes ressemblance avec la réalité n’est que pur hasard