ScalerRefactorer sans tout casser : la méthode incrémentale
· 5 min de lecture · par l'équipe Agenticiel
Le refactoring souffre d’une mauvaise réputation dans les entreprises, parce qu’on le confond avec la refonte. La refonte, c’est tout réécrire, proprement, depuis zéro, et c’est presque toujours un désastre (nous détaillons ce qu’on garde et ce qu’on réécrit lors d’une reprise) : un produit qui a des utilisateurs et qui fonctionne est jeté pour un code neuf qui ne fait pas encore ses preuves, et le temps passé à réécrire est du temps pendant lequel le produit n’évolue plus.
Le refactoring incrémental est l’inverse. Il consiste à améliorer le code par petites étapes, chacune vérifiée par des tests, sans jamais casser ce qui fonctionne et sans jamais interrompre la production. C’est une méthode qui demande de la discipline, pas de l’héroïsme, et c’est la seule façon de réduire la dette technique d’un produit vivant sans le mettre en danger.
Cet article décrit cette méthode : le filet de tests qui la rend possible, le découpage en petites étapes, l’ordre dans lequel s’attaquer au code, et les pièges qui font dérailler les bonnes intentions.
Le préalable : un filet de tests
On ne refactore pas sans filet, et le filet, ce sont les tests. Refactorer, c’est changer la structure du code sans changer son comportement. La seule façon de vérifier que le comportement n’a pas changé, c’est d’avoir des tests qui le décrivent. Sans eux, chaque modification est un pari, et le refactoring se transforme en jeu de hasard.
Le piège est de vouloir tout tester avant de commencer, ce qui est irréaliste sur du code ancien qui n’a jamais été écrit pour ça. La bonne approche consiste à poser des tests de caractérisation : on écrit des tests qui décrivent ce que le code fait réellement, pas ce qu’il devrait faire. Ces tests figent le comportement actuel, même imparfait, et ils deviennent le filet qui permet de changer la structure sans changer le comportement. On les pose sur les chemins critiques d’abord, là où le risque est le plus élevé. Sur du code généré par un assistant, ce filet est souvent inexistant au départ : voir par où commencer pour refactorer du code généré par IA.
Des petites étapes, chacune vérifiée
La règle d’or du refactoring incrémental est de faire des pas si petits que chacun est vérifiable en quelques minutes. On renomme une variable, on extrait une fonction, on déplace un module, et on lance les tests après chaque geste. Les assistants de code comme Claude Code, Cursor ou GitHub Copilot sont efficaces sur ces gestes mécaniques, à condition de leur demander un seul changement à la fois et de relire chaque diff. Une CI, GitHub Actions ou GitLab CI, rejoue ensuite tout le filet avant chaque fusion. Si les tests passent, on continue. S’ils échouent, on sait exactement ce qui a causé l’échec, parce que le pas était minuscule.
Cette discipline paraît lente, elle est en réalité la plus rapide. Un grand refactoring d’un coup produit des erreurs qu’on met des jours à localiser, car tout a changé en même temps. Des petits pas localisent l’erreur immédiatement, et la corrigent en une minute. La lenteur apparente est une illusion : c’est la méthode des grands bonds qui est lente, parce qu’elle paie en débogage ce qu’elle a économisé en précaution.
L’ordre : par l’isolation, pas par la réécriture
On ne s’attaque pas à un code enchevêtré en le réécrivant, mais en l’isolant. La première étape consiste à découper le monolithe en morceaux qui peuvent changer séparément. On identifie les responsabilités mêlées, on trace les frontières, et on déplace le code pour les matérialiser. Chaque frontière posée réduit le périmètre des changements futurs. Quand une partie doit être remplacée, on la fait coexister avec l’ancienne derrière un feature flag, et on bascule le trafic progressivement plutôt qu’en une fois.
Cette isolation précède toute amélioration. Tant que le code est un bloc unique, la moindre retouche a des conséquences partout. Une fois les frontières posées, on peut améliorer un morceau sans toucher aux autres. C’est l’inverse de la tentation naturelle, qui est de réécrire la partie la plus laide d’abord. La partie la plus laide n’est souvent pas la plus urgente, et la réécrire avant d’isoler ne fait que déplacer le problème.
Ne pas refactorer ce qui ne changera pas
Le refactoring a un coût, et il n’a de valeur que s’il est investi là où le code doit évoluer. Refactorer un module stable, qui fonctionne et qu’on ne touchera plus, est un gaspillage. La règle est de refactorer ce qui change souvent, ce qui bloque, ce qui fait peur à modifier. Le reste peut attendre, ou ne jamais être touché.
Cette règle discipline le refactoring. Elle évite le perfectionnisme, qui consiste à nettoyer tout le code par principe, sans lien avec la valeur. Le refactoring n’est pas une fin en soi, c’est un moyen de réduire le coût des changements futurs. Là où il n’y a pas de changement futur, il n’y a pas de retour sur l’investissement.
Mesurer l’effet, pas l’effort
Le refactoring incrémental se mesure à l’effet produit, pas au code réécrit. Le bon indicateur n’est pas le nombre de fonctions réécrites, mais le temps que prennent les changements, la fréquence des incidents, la peur de déployer. Ces mesures se relèvent avant de commencer, et on les compare au fil de la reprise : l’historique Git et la CI donnent la durée des livraisons, un outil de suivi d’erreurs comme Sentry la fréquence des incidents. Elles servent aussi, en amont, à estimer l’ampleur d’une reprise de code avant de s’engager.
Un exemple concret le montre. Une équipe mettait trois jours à livrer une petite évolution, parce que chaque modification traversait un code enchevêtré et cassait autre chose. Après quelques semaines de refactoring incrémental sur les chemins les plus touchés, la même évolution se livrait en une demi-journée. Le code n’était pas plus beau dans l’absolu, mais il était plus rapide à faire évoluer, et c’est la seule chose qui compte.
Le premier pas pour refactorer sans casser
Refactorer sans tout casser est une question de méthode, pas de talent. Sur un produit en production, cela veut dire poser le filet de tests de caractérisation, isoler avant de réécrire, avancer par petites étapes vérifiées, et juger le résultat sur la vitesse des évolutions plutôt que sur la propreté du code.
C’est d’autant plus vrai pour les produits construits vite avec Lovable, Bolt, v0, Cursor ou Claude Code, où la tentation de la refonte est la plus forte et le filet de tests le plus mince. Le point de départ est l’Audit de reprise (750 €, 3 jours) : on repère ce qui change souvent et ce qui bloque, on pose les tests sur les chemins critiques, puis on refactore dans l’ordre qui réduit le coût de vos prochains changements. Votre produit continue de tourner pendant toute la durée du travail.
Si chaque évolution de votre produit prend trois fois plus de temps qu’elle ne devrait, c’est le signal qu’il faut commencer. Le détail de la démarche est sur la page reprendre et scaler un produit.
