Par Michaël Van Damme

Réécrire ou refactoriser : la question à laquelle la plupart des équipes répondent mal

Réécrire ou refactoriser : la question à laquelle la plupart des équipes répondent mal

Tout développeur qui travaille assez longtemps sur une base de code mature connaît ce moment. Le code s'est stratifié au fil des années de modifications. Des décisions ont été prises par des personnes qui ont quitté l'entreprise depuis longtemps. L'architecture ne correspond plus à la manière dont l'application est réellement utilisée aujourd'hui. Et la phrase finit par tomber : « Ce système n'est plus récupérable. On recommence à zéro. »

J'ai vu cette conclusion se tirer souvent. Elle paraît logique, elle procure un sentiment de libération, et elle est généralement fausse.


Pourquoi les réécritures réussissent rarement

Joel Spolsky en a fait un classique dès 2000, dans « Things You Should Never Do » : it's harder to read code than to write it (il est plus difficile de lire du code que de l'écrire). Quiconque lit du code qu'il n'a pas écrit lui-même le trouve presque par définition désordonné. Cela en dit peu sur le code et beaucoup sur la façon dont fonctionne la lecture.

Ce qui compte davantage, c'est ce que contient ce code en apparence désordonné. Un système en production depuis des années recèle une connaissance invisible. L'exception qui a un jour provoqué une escalade chez un client et qui est depuis gérée silencieusement. Une logique métier qui n'est documentée nulle part mais qui est pourtant correcte. Une intégration avec un système externe qui repose sur un comportement subtil dont pas une ligne de documentation ne rend compte.

Cette connaissance n'est pas dans la documentation, car celle-ci est obsolète ou incomplète. Elle n'est pas non plus dans la tête de l'équipe actuelle, car les personnes qui ont fait les choix d'origine sont parties. Elle ne subsiste que dans le code.

Une réécriture jette tout cela à la poubelle. La nouvelle application reproduit les fonctionnalités visibles, et l'on ne découvre la connaissance invisible qu'après coup, réclamation après réclamation, chaque fois qu'un utilisateur signale que quelque chose « fonctionnait avant ». C'est pourquoi les grands projets de réécriture prennent si souvent du retard, voire s'enlisent complètement. Rarement parce que les développeurs n'étaient pas assez compétents. Presque toujours parce que tout le monde avait sous-estimé la complexité du système existant.


Quand réécrire est réellement le bon choix

Je tiens à rester honnête : parfois, il n'y a vraiment pas d'autre solution. Lorsque l'application repose sur un langage ou un framework pour lequel on ne trouve plus de développeurs. Lorsque l'architecture est si fondamentalement défaillante que toute amélioration incrémentale se heurte aux fondations elles-mêmes. Ou lorsque les exigences métier ont tellement changé que le système existant ne constitue plus une base exploitable.

Ce sont des scénarios réels, que nous avons tous déjà rencontrés. Ils sont simplement plus rares que ce que la plupart des équipes pensent au moment où la frustration atteint son sommet.


Ce qu'implique concrètement la refactorisation

Refactoriser n'est pas « faire un peu de rangement ». C'est améliorer la structure d'un système sans en changer le comportement, par petites étapes vérifiables.

À quoi cela ressemble concrètement dépend de l'application, mais le schéma est reconnaissable. Nous commençons presque toujours par la couverture de tests sur les flux critiques, car sans filet de sécurité, chaque modification devient un pari. Vient ensuite le découpage des modules ayant trop de responsabilités, l'extraction de la logique métier hors des contrôleurs et des vues, et la mise à jour des dépendances sans déstabiliser l'ensemble. Chaque étape produit une application qui fait exactement la même chose qu'avant, mais qui devient un peu plus facile à comprendre, à tester et à faire évoluer.

La grande différence avec une réécriture : tout cela se déroule pendant que l'application continue de tourner en production. Pas de big bang, pas de week-end de migration, pas de période où deux systèmes doivent être maintenus en parallèle sans qu'aucun des deux ne soit achevé.


La voie intermédiaire pour les grands systèmes : le strangler fig

Pour les grandes applications, il existe une troisième voie : le pattern strangler fig (figuier étrangleur). On remplace le système module par module. Les nouvelles fonctionnalités sont construites dans la nouvelle architecture, le code existant reste actif entre-temps, et le trafic bascule progressivement de l'ancien vers le nouveau jusqu'à ce qu'il ne reste plus rien de l'ancien système.

Pour les projets de modernisation d'envergure, c'est généralement ainsi que nous travaillons. Le risque reste faible, l'activité de l'entreprise se poursuit, et l'équipe construit tout au long du parcours exactement la connaissance du système qui se perd lors d'une réécriture classique.


D'abord observer, ensuite juger

Chez Refaktory, la préférence est inscrite dans notre nom, on peut donc nous prêter un certain parti pris. C'est pourquoi nous ne commençons jamais par une recommandation, mais par un audit technique : dans quel état se trouve la base de code, où se situent les risques, combien coûte chaque voie sur plusieurs années. Si l'audit conclut que la réécriture est réellement la seule option réaliste, nous le disons, avec les coûts et les risques réels qui l'accompagnent. Un avis qui explose six mois plus tard ne nous est d'aucune utilité.


Questions fréquentes

Comment savoir si mon application est refactorisable ? Pratiquement toute application est refactorisable. La vraie question est de savoir combien de travail cela représente et ce que cela rapporte, et cela varie énormément d'une base de code à l'autre. C'est pourquoi nous commençons toujours par un audit technique.


La refactorisation est-elle moins coûteuse qu'une réécriture ? Dans la plupart des cas, oui, nettement, pour deux raisons. Les projets de réécriture prennent structurellement du retard parce que la complexité de l'ancien système est sous-estimée. Et la refactorisation apporte déjà de la valeur en cours de route, alors qu'une réécriture ne produit un résultat qu'une fois tout terminé.


Peut-on continuer à utiliser l'application pendant une refactorisation ? Oui, c'est précisément l'intérêt de la démarche. L'application continue de tourner en production pendant que le travail s'effectue.


Et si la base de code n'est vraiment plus récupérable ? Alors nous le disons, avec les coûts et les risques réels d'une réécriture. Un avis erroné finit tôt ou tard par nous revenir.


Nous contacter

Quel est votre prochain
défi ?

Nous proposons un premier entretien gratuit pour faire connaissance avec vous, votre activité et vos besoins. Nous vous donnerons un avis honnête sur la manière dont nous pouvons vous aider.

Pas encore convaincu ?

Nom
Nom
E-mail
Téléphone (facultatif)
Sur quoi travaillez-vous ?