Code legacy : tout réécrire ou moderniser par étapes ?
Votre application tourne, mais plus personne n'ose y toucher. Deux voies s'offrent à vous : repartir d'une page blanche ou remplacer l'existant morceau par morceau. Le choix ne se fait pas sur la beauté du code, mais sur quatre critères que vous pouvez évaluer vous-même.
Sommaire
« Il faudrait tout refaire. » Si votre application a plus de dix ans, vous avez forcément entendu cette phrase. Elle vient d’un développeur fatigué de contourner les mêmes fragilités, d’un prestataire qui vous propose une technologie plus moderne, ou de vous-même, un soir où une évolution banale a encore pris trois semaines.
La tentation de la page blanche est compréhensible. Elle n’est pas toujours mauvaise. Mais elle se décide sur des critères précis, et ce ne sont presque jamais ceux qu’on avance en réunion.
Nous avons déjà traité la mesure et le chiffrage de la dette technique. Cet article répond à la question suivante : une fois qu’on sait que l’application doit changer en profondeur, comment change-t-on ?
Deux voies, deux natures de risque
La réécriture complète consiste à reconstruire l’application dans une nouvelle technologie, puis à basculer d’un coup de l’ancienne vers la nouvelle. Le jour de la bascule, tout change.
La modernisation progressive consiste à remplacer l’existant morceau par morceau, en gardant l’application en service du début à la fin. Il n’y a pas de grand jour : il y a une succession de petites bascules, chacune réversible.
Les deux voies ne portent pas le même risque :
| Réécriture complète | Modernisation progressive | |
|---|---|---|
| Quand voit-on le résultat ? | À la fin | Dès la première brique |
| Pendant le chantier | Deux systèmes à payer, aucune nouveauté livrée | Les évolutions continuent, plus lentement |
| Si on arrête à mi-chemin | Rien d’utilisable | Ce qui est fait reste en service |
| Le jour de la bascule | Tout change d’un coup | Une fonction change à la fois |
| Risque principal | Une durée qui dérape | Un chantier qui ne finit jamais |
Le danger de la réécriture n’est pas technique. Il tient au fait qu’on parie sur une durée, et que ce pari se révèle perdu seulement à la fin, quand il est trop tard pour reculer.
Ce n’est pas un constat nouveau. Dès 2000, Joel Spolsky qualifiait dans un article resté célèbre la décision de Netscape de réécrire son navigateur de zéro de « pire erreur stratégique » qu’un éditeur puisse commettre. Son argument tient toujours : un vieux code est laid, mais il contient des années de corrections de cas réels que personne n’a documentées.
Le principe du figuier étrangleur, expliqué simplement
La modernisation progressive a un nom dans le métier : le strangler pattern, ou figuier étrangleur. L’image vient de Martin Fowler, qui l’a décrite sur son site : certains figuiers poussent autour d’un arbre hôte, s’en nourrissent, puis finissent par tenir debout seuls quand l’arbre d’origine a disparu.
Appliqué à une application, cela donne quatre gestes :
- On place un aiguillage devant l’application. Toutes les demandes des utilisateurs passent par ce point d’entrée, qui décide où les envoyer.
- On construit une première fonction dans le nouveau système. Par exemple, la génération des devis.
- On bascule l’aiguillage pour cette fonction seulement. Les devis passent par le nouveau code, tout le reste continue de passer par l’ancien. Si quelque chose ne va pas, on remet l’aiguillage dans sa position initiale.
- On recommence, fonction après fonction, jusqu’à ce que l’ancien système ne serve plus à rien. On le retire alors, sans cérémonie.
Pour l’utilisateur, rien ne se voit, sinon que les écrans modernisés deviennent plus rapides ou plus agréables. Pour vous, chaque étape est un petit projet, avec un début, une fin et un résultat en production.
Martin Fowler résume le constat qui justifie la méthode : le plan simple « on réécrit tout puis on bascule » échoue la plupart du temps, parce que remplacer un système sérieux prend longtemps et que les utilisateurs ne peuvent pas attendre les nouvelles fonctions.
Quatre critères pour trancher
Vous n’avez pas besoin de lire le code pour faire le choix. Il suffit de répondre honnêtement à quatre questions.
1. Connaissez-vous tout ce que fait votre application ? Pas ce qu’elle était censée faire au départ, mais ce qu’elle fait aujourd’hui : la remise particulière de ce client historique, le traitement de fin de mois, l’exception ajoutée il y a six ans. Si ces règles ne sont écrites nulle part ailleurs que dans le code, une réécriture les perdra. La modernisation progressive, elle, les préserve par construction, puisque l’ancien code continue de tourner tant qu’il n’a pas été remplacé.
2. Pouvez-vous suspendre les évolutions pendant plusieurs mois ? Une réécriture mobilise l’équipe sur la reconstruction. Si votre marché exige des nouveautés régulières, la réécriture vous met à l’arrêt face à vos concurrents.
3. Le périmètre est-il petit et borné ? Un outil interne de quelques écrans se réécrit raisonnablement. Une application métier qui irrigue la facturation, la logistique et la relation client, non.
4. La technologie d’origine permet-elle encore d’intervenir ? C’est le seul critère qui pousse franchement vers la réécriture : si l’on ne trouve plus personne pour faire tourner l’environnement, si le langage ne s’exécute plus sur un serveur actuel, on ne peut pas moderniser de l’intérieur.
En pratique, trois réponses favorables à la réécriture sur quatre sont un minimum pour la lancer. En deçà, la modernisation progressive est presque toujours le choix le plus sûr. Et rien n’interdit de combiner : réécrire un module isolé tout en modernisant le reste par étapes.
Les risques que l’on sous-estime
Trois écueils reviennent dans les reprises de code legacy, quelle que soit la voie retenue.
- Les données. On parle beaucoup du code, peu de la base de données. Or c’est elle qui porte quinze ans d’historique, avec ses incohérences. Toute modernisation commence par savoir lire et migrer ces données sans les abîmer.
- Le départ de la mémoire. Si une seule personne comprend encore l’application, le chantier doit commencer par transférer ce savoir, pas par écrire du code.
- La modernisation sans fin. Le revers du figuier étrangleur : à force d’avancer par petites étapes, on peut ne jamais retirer l’ancien système et finir avec deux applications à entretenir. La parade est simple : chaque brique remplacée doit être effectivement retirée de l’ancien code, et l’on suit cette liste comme un indicateur.
Par où commencer
Une modernisation réussie suit presque toujours le même ordre.
- L’inventaire. Ce que fait le système, qui l’utilise, quelles données il manipule, de quoi il dépend. C’est l’objet d’un audit technique, et c’est le document sans lequel aucune des deux voies ne peut être chiffrée.
- Le filet de sécurité. Avant de toucher quoi que ce soit, on écrit des tests qui figent le comportement actuel, y compris ses bizarreries. Ils permettent de vérifier, à chaque étape, que rien n’a changé sans qu’on le décide.
- La première brique. On choisit une fonction utile, assez isolée, dont un éventuel échec resterait sans gravité. Elle sert de preuve : si elle passe en production sans incident, la méthode est validée et le rythme peut s’accélérer.
- Le rythme. On remplace ensuite les briques par ordre de valeur, en commençant par celles qui coûtent le plus cher à faire évoluer aujourd’hui.
Si votre application est aussi votre site public, gardez en tête que la bascule de chaque brique doit préserver les adresses existantes : nous détaillons cette précaution dans notre article sur la refonte sans perte de référencement.
C’est cette démarche que nous appliquons dans nos missions de modernisation de code legacy : un diagnostic d’abord, une première brique ensuite, et une décision à chaque étape sur la suite. La réécriture n’est jamais exclue d’office. Elle doit simplement gagner sa place face à une alternative qui, elle, ne demande pas de parier l’entreprise sur une date.
Retrouvez nos articles en priorité dans vos résultats Google en nous ajoutant à vos sources préférées.
Ajouter aux sources préféréesQuestions fréquentes
Qu'est-ce qu'un code legacy ?
C'est une application ancienne, toujours en production, devenue difficile à faire évoluer : technologie dépassée, absence de tests, documentation perdue, développeur d'origine parti. Ce n'est pas forcément du mauvais code, c'est souvent du code qui a rendu de grands services et qui a survécu à son contexte d'origine.
Pourquoi une réécriture complète est-elle risquée ?
Parce que pendant toute sa durée, vous entretenez deux systèmes et ne livrez rien de nouveau, et parce que l'ancien code contient des règles métier que personne n'a documentées. On les redécouvre une par une, souvent en production. Le risque n'est pas la réécriture en soi, c'est une durée qu'on ne sait pas borner.
Qu'est-ce que le pattern strangler, ou figuier étrangleur ?
C'est une méthode de remplacement progressif : on construit le nouveau système à côté de l'ancien, on lui confie les fonctions une par une, et l'on retire l'ancien quand il ne fait plus rien. L'application reste en service pendant toute la transition et chaque étape peut être annulée.
Dans quels cas vaut-il mieux tout réécrire ?
Quand le périmètre est petit, que les règles métier sont connues et écrites, que la technologie d'origine ne permet plus du tout d'intervenir, ou que le besoin a tellement changé que l'ancien système ne sert plus de référence. Dans ces cas, repartir du besoin est souvent plus rapide que de s'acharner sur l'existant.
Par où commencer une modernisation ?
Par un inventaire de ce que fait réellement le système, puis par des tests qui figent son comportement actuel. Ensuite, on choisit la première brique à remplacer : une fonction utile, assez isolée, dont l'échec éventuel resterait sans gravité. Elle sert de preuve avant d'engager la suite.