Dans cet article, je vais vous exposer 8 règles issues du livre Clean Code de Robert C. Martin, permettant d’améliorer le nom de vos variables, fonctions et classes.
Sommaire
Introduction
En programmation, nous sommes régulièrement amenés à choisir des noms, que ce soit pour des variables, des fonctions ou encore des classes.
Je peux parier que vous vous êtes déjà retrouvé dans la situation, ou l’inspiration vous manquait, et vous étiez tellement désespéré de ne pas trouver un nom que vous vous êtes dit : “Je vais nommer cette variable x et on changera plus tard”. Vous voilà prévenu, nommer sa variable x est une grave erreur. Il y a deux risques majeurs à faire cela. Le premier est que vous oubliez de changer le nom de la variable et le deuxième c’est qu’un autre développeur passe derrière vous et ne comprend pas le sens de cette variable.
Il ne faut pas oublier qu’être développeur c’est avant tout être auteur. Vous écrivez du code qui devra être lu et relut par d’autres développeurs. En moyenne vous passez 80% de votre temps à lire du code et 20% à en écrire. Il est donc primordial de donner des noms qui ont du sens.
Notre but, en tant qu’auteur est d’écrire du code le plus facilement compréhensible.
-- Clean Code - Robert C. Martin
Règles
1. Un nom doit être explicite
Le nom que vous choisissez doit révéler les intentions de ce qu’il nomme.
Choisir un bon nom prend du temps mais en fait économiser encore plus.
-- Clean Code - Robert C. Martin
Mauvaise pratique 👎
d: number; //Day before end of the year
Bonne pratique 👍
dayBeforeEndOfYear: number;
dayByEndOfYear: number;
Exemple de la fonction suivante :
function getDays(d1: number, d2: number): number {
const d: number = d2 - d1;
return Math.ceil(d / (1000 * 60 * 60 * 24))
}
Dans cet exemple de 3 lignes nous avons plusieurs questions :
- Que représentent d1 et d2 ?
- Que représente d ?
- Que représente le calcul 1000 * 3600 * 24 ?
- La question principale est : Que fait cette fonction ?
Avez-vous compris du premier coup d’œil que cette fonction renvoie le nombre de jours avant la fin de l’année ?
Autant de ligne que de questions. En appliquant la règle précédente on obtient :
function getDaysByEndOfYear(todayTimestamp: number, endOfYearTimestamp: number): number {
const millisecondsByYear: number = 1000 * 60 * 60 * 24;
const durationByEndOfYear: number = endOfYearTimestamp - todayTimestamp;
return Math.ceil(durationByEndOfYear / millisecondsByYear)
}
On remarque que d1 et d2 sont des timestamps du jour et de la fin d’année, que d est la durée qui sépare le jour actuel de la fin d’année et enfin que la constante est le nombre de millisecondes dans une année. Toutes ces choses ne sont pas faciles à déduire. Le fait de mettre des noms explicites permet de comprendre assez vite avec quoi nous travaillons.
Le problème n’est pas que le code soit simple mais que le code soit implicite.
-- Clean Code - Robert C. Martin
2. Un nom ne doit pas donner de fausses informations
Il faut à tout prix éviter de donner un nom qui fait penser à autre chose que ce pourquoi le nom a été créé.
Un exemple simple est de nommer une collection userList. A moins que cette collection soit toujours une list, il est plus sage de donner le nom users. En effet, userList pourrait être une map, un array, une linked list ou autre. Avec users, on obtient autant d’information sans inférer un sens que la variable n’a pas.
Il faut également éviter les noms avec des caractères ambigus comme 1 et l ou 0 et O. Ce genre de caractères peuvent être confondu en fonction de la police utilisée par l’IDE.
La clarté est reine. Les professionnels tirent profit du pouvoir de la clarté en écrivant du code compréhensible pour les autres.
-- Clean Code - Robert C. Martin
3. Un nom égale un concept
Il est important de choisir un mot par concept et de s’y tenir. Cela permet d’avoir une cohérence et de développer un langage métier du projet dans lequel vous travaillez.
Dans cet exemple, on utilise trois mots différents pour parler d’un même concept qui est : requêter des données sur un serveur.
Mauvaise pratique 👎
getUsers();
retrieveRoles();
fetchAccounts();
Bonne pratique 👍
getUsers();
getRoles();
getAccounts();
La raison pour laquelle il faut éviter d’utiliser plusieurs mots pour un concept est que lorsque vous recherchez dans votre IDE toutes les occurrences d’un concept, il est important d’avoir tous les noms qui relatent de ce concept en une fois. S’il y a plusieurs mots pour un concept alors il est possible que vous passiez à côté d’une partie de la logique. De même, si un concept différent apparait dans la liste des noms, vous vous retrouverez à renommer ou à traiter des noms qui n’ont aucun rapport avec l’action que vous voulez réaliser.
4. Faire des distinctions qui ont du sens
Say what you mean. Mean what you say.
-- Clean Code - Robert C. Martin
Imaginez que vous avez deux classes : ProductInfo et ProductData. Comment pouvez-vous savoir quelle classe utiliser pour réussir à implémenter votre fonctionnalité de la façon la plus simple possible ? C’est impossible, il n’y a aucune différence entre info et data.
En réalité info et data n’ajoutent que du bruit. Les mots qui ajoutent du bruit sont à bannir.
Des noms distincts sont une façon de fournir au lecteur du code quelle est la différence de logique entre deux noms.
-- Clean Code - Robert C. Martin
Ne perdez également pas de vu que vous rédigez du code pour des développeurs. N’hésitez pas à utiliser le langage que les développeurs comprennent tel que view, model, controller, service, store etc …
5. Un nom doit être prononçable
Il est simple pour le cerveau d’interpréter des mots dans une phrase. Il est plus difficile d’interpréter des abréviations. Imaginer que vous lisez un code pour la première fois et que vous n’avez pas encore intégré l’ensemble des acronymes de votre projet. C’est une véritable torture d’interpréter le code sans comprendre les noms.
Il faut à tout prix éviter les raccourcit dans les noms. Ce qui était vrai avant ne l’est plus aujourd’hui. La taille de nos variables n’impacte plus les performances de notre programme.
Mauvaise pratique 👎
genymdhms: number;
modymdhms: number;
Bonne pratique 👍
generationTimestamp: number;
modificationTimestamp: number;
N’oubliez pas que l’on passe la plupart de notre temps à lire du code, donc il est possible de perdre énormément de temps avec des noms peu explicite.
6. Un nom doit être recherchable
Il faut éviter au maximum les noms court avec une, deux ou trois lettres. Ces noms sont difficilement recherchables. Si vous cherchez dans votre projet la variable "e" vous aurez tous les noms comportant la lettre "e", ça peut faire un sacré paquet de noms !
Une règle simple est d’utiliser les variables à une lettre uniquement dans les variables locales d’une petite méthode comme une lambda fonction.
La taille d’une variable dépend de la porté de cette dernière.
-- Clean Code - Robert C. Martin
Plus une variable est globale, plus elle doit être explicite.
Lorsque vous avez des constantes dans votre code, éviter de mettre des nombres en dur. Il y a plusieurs raisons à cela :
- Si quelqu’un d’autre lit votre code comment sait-il la signification du chiffre 5 ?
- Si vous voulez changer la valeur de la constante il faut le faire à tous les endroits où cette constante est utilisée.
- Si plusieurs constantes ont la même valeur mais pas la même signification on ne peut pas les distinguer.
Mauvaise pratique 👎
const price: number = itemQuantity * 54.5;
Bonne pratique 👍
const ITEM_COST: number = 54.5;
const price: number = itemQuantity * ITEM_COST;
Lorsque vous devez chercher le prix d’un item, vous pouvez facilement le trouver. Il est également facile de changer ce prix car il suffit de changer la valeur de ITEM_COST. Si la variable est utilisée à plusieurs endroits, vous vous assurez de changer uniquement cette dernière est de façon uniforme.
7. Les noms de classes et de fonctions
Nom de classe
Une classe doit toujours être nommée par un nom comme Customer, Account ou AddressParser.
Une classe ne doit jamais être nommé par un verbe !
Nom d’une fonction ou méthode
Une fonction doit toujours être nommé par un verbe comme postPayment, deletePage ou save. Les verbes get et set sont communs pour les méthodes de classe.
8. Ajouter du contexte pour ajouter du sens
Il est parfois très dur de donner du sens à un mot. Il existe une solution pour cela, il suffit d’encapsuler ce nom dans une classe une fonction ou un namespace. Ce nom prendra ainsi son sens dans ce contexte et il sera alors beaucoup plus simple de comprendre à quoi il sert.
Prenons comme exemple : street, house number, city, state, zipcode.
Prit tous ensemble, nous comprenons qu’il s’agit d’une adresse, mais qu’en est-il si on isole state ? State peut avoir plusieurs significations. Il peut être intéressant d’ajouter address devant le nom pour donner du contexte ou l’englober dans une classe Address.
Mauvaise pratique 👎
state: string;
Bonne pratique 👍
// solution 1
addressState: string;
// solution 2
class Address {
state: string;
}
Ne pas ajouter du contexte inutilement
Imaginez que votre projet s’appelle My Awesome Project. Si vous ajouter MAP devant toute vos variable fonction ou classe comme ceci MAPAddress MAPUser ou encore mapAccount, vous vous retrouverez à ajouté du contexte inutile.
Il faut garder en tête que les noms de variables doivent être le plus court possible dans la mesure où ils restent compréhensibles.
Exemple :
Si on a PostalAddress, MACAddress et URIAddress, on préférera mettre PostalAddress, MAC et URI car MAC et URI sont explicitement des adresses.
Conclusion
Pour résumer, une variable doit être la plus courte possible tout en ayant un maximum de sens. Il faut s’efforcer de donner du sens et éviter les variables trop courtes à moins de 3 lettres ou des acronymes. Les mots ajoutant des informations potentiellement fausses comme list sur une collection sont à bannir.
Chaque mot doit être attaché à un contexte. Si deux mots font référence au même contexte, ou qu’un mot peut signifier plusieurs contextes à la fois, alors il y a possibilité d’erreur.
Favorisez les variables qui sont prononçable c’est à dire qui sont facilement compréhensible. N’oubliez pas que vous parlez à des humains et qu’un humain à besoin de sens pour comprendre.
Il est important qu’un nom soit recherchable facilement. En effet dans les IDE, la fonctionnalité qui permet de rechercher un terme dans une application est très pratique et fait gagner beaucoup de temps.
Veuillez à bien utiliser des noms pour les classes et des verbes pour les fonctions et méthodes.
TLDR
Voici une grille qui vous permettra de voir si les noms que vous choisissez pour vos variables, classes, fonctions respectent les bonnes pratiques enseignées par Clean Code de Robert C. Martin.
Au moindre non vous devez changer le nom que vous avez donné !
Règles | 👍 | 👎 |
---|---|---|
Ma variable n’a pas besoin de commentaire pour avoir du sens. | ||
Ma variable ne peut pas faire référence à autre chose. | ||
Ma variable n’est pas un acronyme. | ||
Ma variable a plus de 3 lettres ou ces 3 lettres sont compréhensibles. | ||
Ma variable ne contient pas les mots : string, data, list, object etc … | ||
Ma variable est facilement recherchable dans mon IDE. | ||
Si c’est une classe, ma variable comporte un nom et pas de verbe. | ||
Si c’est une fonction, ma variable comporte un verbe. | ||
Si ma variable n’a pas de sens par elle-même alors elle est encapsulée dans une classe ou une fonction. | ||
Ma variable fait référence au domaine informatique ou au domaine métier. |
Top comments (2)
Superbe idée d'article.
Cet exercice d'expliquer chacune des règles, n'est pas simple.
J'ai trouvé la lecture de ces 8 règles laborieuses, c'est peut-être parce que je les connaissais déjà. Cela me fait une bonne révision tout de même.
Permets-moi de compléter les informations.
La taille des noms
Nommer les classes
Mots parasites
Suffixes
Info
Data
Manager
Processor
Handler
Préfixes
a
the
Nommer les interfaces
L'intérêt d'une interface est que les utilisateurs ne savent pas qu'il s'agit d'une interface.
I
ni aucun suffixe tel queInterface
, notation hongroise.Exemple :
Account
comme nom de l'interfaceUserAccount
comme nom de l'implémentation.Pas au pluriel !
Le nom de la classe devrait terminer avec un nom commun au singulier.
Pour une liste de
Kind
, ne l'appelez pasKinds
.Vous devriez probablement l'appeler
KindList
.Exemple :
Employee
EmployeeList
La table de la base de données doit s'appeler
employee
et nonemployees
.Sous-classe
Les sous-classes sont préfixées avec un adjectif.
Elles spécialisent la classe mère.
Exemple :
DateProvider
DeterministicDateProvider
Merci pour tes retours ! Je fais en sorte que chaque article soit de plus en plus compréhensible, c’est en forgeant que l’on devient forgeron 😁