Dette technique : les trois signaux qui justifient un refactoring, et ceux qui n’en justifient aucun
Tout le monde parle de dette technique, très peu la mesurent. Résultat : on refactore ce qui gêne l’équipe plutôt que ce qui coûte à l’entreprise, et on s’étonne que la direction ne financera jamais le chantier.
Christophe Bellec ·
Réponse courte
Un refactoring se justifie quand le code freine une évolution demandée, quand il provoque des incidents répétés, ou quand il bloque le recrutement et l’autonomie de l’équipe. Le code laid, ancien ou écrit autrement que ce qu’on ferait aujourd’hui ne justifie rien par lui-même : de la dette dans une zone stable que personne ne touche ne coûte rien. La question n’est pas « ce code est-il bon ? » mais « ce code nous coûte-t-il quelque chose de mesurable ? »
La dette n’est pas la laideur
La dette technique, c’est un choix passé qui rend les changements futurs plus coûteux. Le mot important est « futurs » : s’il n’y a pas de changement prévu dans une zone, la dette qui s’y trouve ne coûte rien, quelle que soit la tête du code.
Cette nuance est ce qui distingue un refactoring qui se finance d’un refactoring qu’on ne vous accordera jamais. « Ce code est sale » n’est pas un argument. « Cette zone a absorbé 40 % de notre temps de développement ce trimestre » en est un.
Les trois signaux qui justifient d’intervenir
Signal 1 : le code freine une évolution demandée
Une fonctionnalité au périmètre modeste demande un effort disproportionné, ou l’estimation explose parce qu’il faut toucher cinq endroits sans rapport apparent. La dette devient alors un coût directement imputable à la roadmap.
Ce qui le rend visible : comparer l’effort estimé au périmètre fonctionnel réel, sur plusieurs évolutions. Si l’écart se concentre toujours sur les mêmes modules, vous tenez votre cible.
Signal 2 : les mêmes incidents reviennent
Une zone produit régulièrement des régressions, ou une correction en casse une autre. Ici la dette ne coûte plus seulement du temps de développement : elle coûte de la disponibilité, de la confiance client et du temps de support.
Le signal fiable est la répétition. Un incident isolé se corrige ; un incident qui revient sous des formes voisines indique un problème de conception, pas un bug.
Signal 3 : la connaissance ne circule pas
Une seule personne sait faire évoluer un module, un nouvel arrivant met des semaines à livrer sa première modification, ou l’équipe évite systématiquement une zone. C’est un risque organisationnel plus que technique, et c’est celui qui se paie le plus cher au moment d’un départ.
Ces trois signaux ont un point commun : ils se constatent sans lire une ligne de code. C’est ce qui les rend utilisables dans une discussion avec une direction non technique.
Cinq raisons qui n’en sont pas
- « Ce n’est pas comme ça qu’on écrirait aujourd’hui. » Probablement vrai, et sans conséquence si personne n’y touche.
- « Le framework a une nouvelle version majeure. » Une mise à jour se justifie par le support, la sécurité ou une fonctionnalité nécessaire, pas par le numéro de version.
- « Il n’y a pas de tests. » Ajouter des tests sur une zone stable et sans incident n’apporte rien. Sur un chemin critique modifié chaque mois, c’est prioritaire.
- « C’est monolithique. » Un monolithe bien découpé fonctionne très bien. Le découpage en services résout un problème d’organisation et de déploiement, pas un problème de propreté.
- « L’équipe préférerait travailler avec autre chose. » C’est une vraie question de recrutement et de motivation, mais il faut la traiter comme telle, pas la déguiser en argument technique.
Mesurer sans monter une usine
Quatre indicateurs suffisent, et ils s’obtiennent avec ce que vous avez déjà :
- Le ratio construction / correction, par trimestre. S’il dérive, la dette progresse plus vite que vous ne la remboursez.
- Les fichiers qui changent le plus souvent, extraits de l’historique du dépôt. Ce sont eux qui méritent d’être propres, pas ceux qui n’ont pas bougé depuis deux ans.
- Les fichiers qui changent souvent ensemble. Un couplage fort et invisible s’y lit directement.
- Le délai entre « prêt » et « en production ». Il mesure la friction de tout le cycle, pas seulement du code.
Le croisement des points 2 et 3 avec les zones à incidents suffit généralement à désigner deux ou trois cibles. C’est beaucoup plus opérant qu’un outil qui note la qualité du code sur cent.
Comment rembourser sans arrêter la roadmap
Le grand refactoring isolé, mené en parallèle du développement produit, échoue presque toujours : il diverge, puis la fusion devient impossible.
- Refactorer là où on passe : chaque fois qu’une fonctionnalité touche une zone à dette, on améliore cette zone dans la foulée, à périmètre maîtrisé.
- Isoler avant de réécrire : poser une interface stable devant la zone problématique, puis changer ce qu’il y a derrière sans que le reste s’en aperçoive.
- Écrire les tests juste avant de modifier, pas « un jour » : ils servent de filet pour la modification en cours.
- Se donner un critère de sortie : « cette zone ne doit plus apparaître dans les trois modules les plus modifiés au prochain trimestre ».
- Documenter la décision : ce qu’on a changé, pourquoi, et ce qu’on a délibérément laissé en l’état.
La dette qu’il faut assumer
Une partie de la dette doit rester. Un module stable, sans incident, que personne ne modifie, peut rester tel quel indéfiniment, même s’il est laid. Le rendre élégant consomme du budget pour zéro bénéfice et introduit un risque de régression là où il n’y en avait aucun.
Assumer explicitement cette dette-là est un acte d’architecture. Elle doit être écrite quelque part, avec la raison de ne pas la traiter et le signal qui remettrait la question sur la table. Sinon elle sera re-débattue tous les trimestres.
Questions fréquentes
Comment convaincre une direction de financer un refactoring ?
En traduisant la dette en effets mesurés : temps de développement absorbé par une zone, incidents répétés, délai de mise en production, dépendance à une seule personne. Un argument formulé en termes de qualité de code n’est presque jamais financé ; un argument formulé en coût et en risque l’est souvent.
Faut-il refactorer avant ou après une nouvelle fonctionnalité ?
Juste avant, et sur le périmètre strictement concerné. On stabilise la zone qu’on s’apprête à modifier, on livre la fonctionnalité, on s’arrête là. Le refactoring « pour plus tard » n’arrive jamais, celui « tant qu’on y est » n’a plus de limite.
Une réécriture complète est-elle parfois la bonne réponse ?
Rarement, mais oui : quand la technologie n’est plus supportée, quand plus personne ne sait faire évoluer le système, ou quand le modèle métier a fondamentalement changé. Il faut alors l’assumer comme un projet à part entière, pas la présenter comme un refactoring.
Quel est le bon rythme de remboursement ?
Il n’existe pas de pourcentage universel. Le repère utile est le ratio construction / correction : tant qu’il reste stable d’un trimestre à l’autre, le rythme actuel suffit. S’il se dégrade, la dette progresse plus vite qu’elle n’est remboursée.