Le scenario que tout dirigeant redoute
Imaginez. Votre application est en production. Des milliers d’utilisateurs s’en servent quotidiennement. Elle genere du chiffre d’affaires. Et du jour au lendemain, la personne qui l’a construite n’est plus la.
Pas de preavis. Pas de passation. Pas de documentation. Juste une application qui tourne — et un depot Git dont personne ne comprend le contenu.
C’est exactement ce qui est arrive a MyMove.
MyMove compare les tarifs VTC en temps reel. Uber, Kapten, Bolt, G7, et d’autres. L’application interroge 5 APIs heterogenes, unifie les resultats, et propose le meilleur prix au client. Sur le papier, c’est un comparateur. En pratique, c’est un systeme d’integration complexe qui depend de 5 fournisseurs externes — chacun avec sa propre API, son propre format de donnees, ses propres caprices, et son propre rythme de breaking changes.
Le prestataire original ? Disparu. Sans laisser de documentation. Sans laisser de tests. Sans meme laisser des commentaires dans le code.
Ce qu’on a trouve en arrivant
Michael Feathers, l’auteur de Working Effectively with Legacy Code, definit le code legacy comme “du code sans tests.” Par cette definition, l’application MyMove etait du code legacy dans sa forme la plus pure.
Le diagnostic en 5 points
1. Aucune documentation. Ni technique, ni fonctionnelle. Pas de README, pas de schema d’architecture, pas de description des flux de donnees. La seule documentation existante etait le code lui-meme — et il ne se commentait pas.
2. Cinq integrations, cinq facons de faire. Chaque API VTC etait integree differemment. Pas de logique commune, pas de pattern partage. L’integration Uber utilisait des callbacks, Bolt utilisait du polling, Kapten passait par un webhook. Chaque ajout de fournisseur avait ete fait par-dessus le precedent, sans refactoring.
3. Zero tests. Pas un seul test automatise. Chaque modification etait un pari : on deployait, on croisait les doigts, et on attendait les plaintes des utilisateurs.
4. Des corrections en urgence permanentes. Uber change le format d’une reponse API ? Hotfix en production a 22h. Bolt modifie son endpoint d’authentification ? Hotfix le samedi matin. Le prestataire passait plus de temps a eteindre des incendies qu’a construire des fonctionnalites. C’est d’ailleurs probablement ce qui l’a fait fuir.
5. Une equipe paralysee. L’equipe MyMove n’osait plus rien demander. Chaque demande d’evolution etait accueillie par “c’est risque” ou “ca peut tout casser.” L’application tournait, mais elle etait devenue intouchable — un chateau de cartes qui s’effondrait a la moindre brise.
La methode : documenter d’abord, coder ensuite
Quand on reprend un projet sans documentation, la tentation est de se jeter sur le code. De commencer a corriger, a refactorer, a “ameliorer.” C’est la pire chose a faire. Comme l’ecrit Michael Feathers : avant de changer du code que vous ne comprenez pas, vous devez d’abord comprendre ce qu’il fait — pas ce qu’il devrait faire.
Semaine 1 — Cartographier avant de toucher
On n’a pas ecrit une seule ligne de code pendant la premiere semaine. A la place :
Cartographie des flux de donnees. Chaque requete utilisateur, de l’entree a la sortie. Quelles APIs sont appelees, dans quel ordre, avec quels parametres, quels formats de reponse, quels cas d’erreur.
Tests de caracterisation. C’est une technique decrite par Michael Feathers : on ecrit des tests qui decrivent ce que le code fait reellement, pas ce qu’il devrait faire. On lance l’application, on observe les entrees et sorties, et on fige ce comportement dans des tests. C’est le filet de securite qui permet de modifier le code ensuite sans casser l’existant.
Inventaire des dependances critiques. Quelles bibliotheques, quelles versions, quels services externes, quelles cles API. Avec pour chacun : est-ce a jour ? Est-ce maintenu ? Est-ce un risque ?
A la fin de la semaine 1, on avait ce que le prestataire d’origine n’avait jamais produit : une carte du territoire. Pas parfaite, mais suffisante pour avancer en securite.
Semaines 2 a 3 — Restructurer pour la durabilite
Avec les tests de caracterisation en place, on pouvait enfin toucher au code sans risque. L’objectif n’etait pas de tout reecrire — c’etait de creer une structure uniforme pour les 5 integrations VTC.
Le pattern adaptateur. On a cree un adaptateur par API VTC. Chaque adaptateur respecte la meme interface : une methode getQuote(origin, destination) qui retourne un format de sortie commun. Le code appelant ne sait pas s’il parle a Uber, Bolt, ou G7 — il parle a un adaptateur standardise.
Ce pattern est un classique de Working Effectively with Legacy Code : on isole le code externe derriere une interface controlable. Les benefices sont immediats :
- Ajouter un nouveau fournisseur = creer un nouvel adaptateur, sans toucher au reste
- Un fournisseur change son API = modifier un seul adaptateur, pas l’ensemble du systeme
- Tester = moquer les adaptateurs, tester la logique metier independamment
Application de la Boy Scout Rule. A chaque fois qu’on touchait a un fichier, on le laissait un peu plus propre : nommage coherent, suppression du code mort, ajout de commentaires la ou la logique etait complexe. Robert C. Martin appelle ca le nettoyage opportuniste — on ne fait pas de grand projet de refactoring, on ameliore au passage.
Semaine 4 — Surveiller et prevenir
Le code etait stabilise. Mais sans surveillance, les memes problemes reviendraient au premier changement d’API externe.
Monitoring proactif. Des alertes automatiques quand une API externe retourne des erreurs inhabituelles. Quand Uber change un format de reponse, on le sait en 5 minutes — pas quand un utilisateur se plaint 48h plus tard.
Tests de contrat. Pour chaque API externe, un test qui verifie que le format de reponse n’a pas change. S’il change, le test echoue, et l’equipe est alertee avant que ca impacte les utilisateurs.
Pipeline de deploiement. Integration continue, deploiement automatise, rollback en un clic. Plus de hotfixes a 22h deployes a la main sur le serveur de production.
Les resultats en chiffres
| Indicateur | Avant | Apres |
|---|---|---|
| Integration d’un nouveau fournisseur | 3 semaines | 3 jours |
| Incidents en production par mois | 8-12 | 1-2 |
| Temps de resolution d’un incident | 4-8 heures | < 30 minutes |
| Tests automatises | 0 | 180+ |
| Documentation | Inexistante | Complete |
| Equipe autonome | Non | Oui |
Le cout total de la reprise etait inferieur a 20% de ce qu’aurait coute une refonte complete. Et l’application n’a jamais ete interrompue.
Les lecons a retenir pour votre projet
1. Ne jamais coder avant de comprendre
C’est la lecon la plus contre-intuitive. Quand on herite d’un projet en crise, l’urgence pousse a agir. Mais coder sans comprendre dans du code sans tests, c’est exactement comme ca qu’on transforme un chateau de cartes en ruines.
2. Les tests de caracterisation sont votre filet de securite
Avant de changer quoi que ce soit, figez le comportement actuel dans des tests. Meme si le comportement n’est pas ideal. Meme s’il contient des bugs connus. Le but est de garantir que vos modifications ne cassent pas ce qui fonctionne.
3. Le pattern adaptateur resout 80% des problemes d’integration
Si votre application depend de services externes, isolez chaque dependance derriere une interface standardisee. C’est le principe d’inversion des dependances — un fondamental de l’architecture logicielle que les auteurs de The Pragmatic Programmer placent au coeur de tout systeme maintenable.
4. Un projet “non maintenable” est rarement perdu
En general, 2 a 4 semaines de reprise structuree suffisent a remettre les choses sur les rails. Pas a rendre le code parfait — a le rendre maintenable, testable, et evolutif. C’est la difference entre un systeme qu’on subit et un systeme qu’on maitrise.
5. La documentation est un investissement, pas un luxe
Un projet sans documentation est un projet en sursis. Chaque heure investie en documentation au debut en economise dix plus tard. Ce n’est pas une opinion — c’est une constante qu’on observe sur chaque reprise depuis 14 ans.
Le cout de la reprise vs. la refonte
La question qui revient systematiquement : “n’aurait-il pas ete plus simple de tout refaire ?” Non. Et les chiffres le demontrent.
| Approche | Cout estime | Delai | Risque d’interruption |
|---|---|---|---|
| Refonte complete | 60 000 a 120 000 euros | 4-8 mois | Eleve |
| Reprise structuree | 15 000 a 35 000 euros | 4 semaines | Nul |
La reprise a coute moins de 20% du prix d’une refonte. L’application n’a jamais ete interrompue. Et l’equipe MyMove etait autonome a la fin du mois — pas dans 8 mois.
Comme l’ecrit Martin Fowler a propos du Strangler Fig Pattern : on peut presque toujours remplacer un systeme de maniere incrementale, sans le risque d’un big bang. MyMove en est la demonstration.
Quand la reprise ne suffit pas
La methode que nous venons de decrire fonctionne dans la grande majorite des cas. Mais il existe des situations ou la reprise structuree atteint ses limites :
- La technologie est abandonnee — le framework n’est plus maintenu, les dependances n’ont plus de mises a jour de securite
- L’architecture fondamentale est incompatible avec les besoins actuels — par exemple, un systeme synchrone qui doit devenir temps reel
- Le cout de la stabilisation depasse celui de la reconstruction — on l’a vecu avec chocobonplan, ou la reecriture etait la seule option viable
Dans ces cas precis, la reecriture peut etre justifiee. Mais meme alors, on l’execute avec la meme discipline : en parallele de l’ancien systeme, par migration progressive, sans interruption de service.
Le framework de reprise en resume
| Phase | Duree | Objectif | Livrable |
|---|---|---|---|
| Cartographie | 3-5 jours | Comprendre l’existant | Schema d’architecture, inventaire |
| Caracterisation | 3-5 jours | Figer le comportement dans des tests | Suite de tests, documentation |
| Restructuration | 2-3 semaines | Rendre le code maintenable | Code refactore, adaptateurs |
| Surveillance | 1 semaine | Prevenir les regressions | Monitoring, alertes, CI/CD |
| Transfert | En continu | Rendre l’equipe autonome | Formation, documentation |
La methode tient en 3 mots : documenter d’abord, restructurer ensuite. Pas l’inverse.
Vous avez herite d’un projet sans documentation ? On fait ca depuis 14 ans.