L'éloge de la paresse en ingénierie logicielle
Alexandre Jeffroy
Ingénieur logiciel
Dans l'imaginaire collectif, le bon développeur est une personne acharnée, capable de passer des heures à coder sans relâche. Je crois pourtant l'inverse : l'une des qualités les plus utiles d'un bon ingénieur est une forme de paresse. Pas l'oisiveté, mais une aversion viscérale pour l'effort inutile, qu'il soit présent ou à venir.
Ce n'est pas un hasard si Larry Wall, le créateur de Perl, citait la paresse comme l'une des trois grandes vertus du programmeur. Ce n'est pas un trait de caractère qu'on cultive par confort. C'est un raisonnement.
Deux formes de paresse, un seul réflexe
La première paresse pousse à automatiser une tâche répétitive ; j'en ai déjà parlé dans un précédent article sur la charge mentale. La seconde est plus discrète, et elle agit avant même que le code soit écrit : c'est celle qui pousse à choisir la solution la plus simple possible pour ne pas avoir à la maintenir, à la recomprendre ou à la déboguer plus tard.
Un développeur vraiment paresseux n'écrit pas la solution la plus impressionnante. Il écrit celle qui lui demandera le moins d'efforts *plus tard*, quitte à en fournir un peu plus maintenant.
L'exemple du code qu'on ne veut plus jamais relire
Sur un projet de simulation temps réel, j'ai vu une fonction de calcul de trajectoire réécrite trois fois en un an, à chaque fois pour corriger un cas limite oublié. En cause : une implémentation « astucieuse », optimisée à outrance dès la première version, difficile à relire et donc difficile à corriger correctement.
La bonne paresse aurait dit : écris d'abord la version la plus simple et la plus lisible, et n'optimise que si le profilage le justifie. Le développeur qui a fini par stabiliser cette fonction l'a justement réécrite de façon plus simple, avec des noms de variables explicites et une structure évidente. Depuis, plus aucune régression.
1// Version "astucieuse" — rapide à écrire, coûteuse à comprendre
2double f(double v, double a, double t) {
3 return v*t + 0.5*a*t*t - (v<0?v*t:0);
4}
5
6// Version "paresseuse" — un peu plus longue, jamais mal comprise
7double computeDisplacement(double initialSpeed, double acceleration, double time) {
8 const double distance = initialSpeed * time + 0.5 * acceleration * time * time;
9 const bool movingBackward = initialSpeed < 0.0;
10 return movingBackward ? distance - initialSpeed * time : distance;
11}La paresse comme filtre à complexité
Cette aversion pour l'effort futur agit comme un filtre naturel contre la sur-ingénierie. Face à une nouvelle fonctionnalité, je me pose toujours la même question : *est-ce que je veux vraiment avoir à maintenir ça dans six mois ?* Si la réponse est non, je cherche une solution plus simple, quitte à ce qu'elle paraisse, sur le moment, moins élégante ou moins généraliste.
C'est aussi ce réflexe qui pousse à dire non à une abstraction prématurée. Pourquoi construire un système de plugins générique pour un besoin qui, en réalité, ne concernera jamais que deux cas connus et stables ? La paresse intelligente préfère deux fonctions simples à une architecture qu'il faudra comprendre avant même de la faire évoluer.
Le vrai risque : la fausse paresse
Il existe une paresse dangereuse, qui n'a rien à voir avec celle dont je parle : celle qui consiste à bâcler pour aller plus vite maintenant, quitte à laisser une dette technique invisible. Ce n'est pas de la paresse, c'est de la précipitation. La vraie paresse est stratégique : elle accepte un coût aujourd'hui pour économiser un coût plus grand demain.
La paresse comme stratégie
La prochaine fois que vous verrez un développeur passer du temps à simplifier une solution qui « fonctionnait déjà », ou refuser une fonctionnalité mal définie tant qu'elle n'est pas clarifiée, ne le jugez pas paresseux au mauvais sens du terme. C'est souvent le signe d'un ingénieur qui a déjà anticipé l'effort qu'il vous évite.
Autres articles
Workbench : mon couteau suisse pour éliminer les actions répétitives
Workbench est l'outil qui sert de socle à toute ma démarche d'outillage interne. Une interface graphique unique qui regroupe les actions répétitives du quotidien et remplace une poignée de commandes fastidieuses par quelques clics.
SonarQube : maîtriser la qualité et la dette technique
Dans des secteurs où la fiabilité n'est pas négociable, comment s'assurer que des centaines de milliers de lignes de code respectent les standards les plus élevés ? SonarQube est devenu un allié indispensable sur mes projets.