Dans le monde du logiciel, cinq ans peuvent aussi bien désigner un système encore très bien préparé à évoluer qu’un problème technologique qui coûtera de plus en plus cher à chaque mois qui passe.
L’âge de l’application, à lui seul, n’est toutefois pas une raison de la remplacer.
C’est l’une des choses les plus importantes à dire dès le départ.
Il n’existe pas de seuil universel au-delà duquel il faudrait réécrire une application de zéro. Il existe des systèmes qui fonctionnent depuis une dizaine d’années et qui ont encore une architecture sensée, des dépendances à jour, une bonne documentation et un processus de déploiement éprouvé. Il existe aussi des applications beaucoup plus jeunes dont le développement a été compliqué par de mauvais choix architecturaux, un manque de tests, des dépendances non maîtrisées ou des correctifs rapides successifs.
Le problème n’est donc pas le nombre d’années.
Le problème, c’est la capacité du système à continuer d’évoluer.
La question la plus importante n’est pas : "L’application est-elle ancienne ?"
La meilleure question est : "Combien nous coûte le prochain changement ?"
Si l’ajout d’une nouvelle fonctionnalité exige de plus en plus d’heures, l’implication de plusieurs équipes, des tests manuels et des contournements des limites d’une ancienne architecture, le système commence à générer un coût qui n’apparaît pas dans le code lui-même.
C’est précisément l’un des signes pratiques d’une dette technique croissante.
La dette technique peut être comprise comme le coût des changements futurs résultant de décisions techniques prises auparavant. Martin Fowler la décrit comme l’effort supplémentaire qu’il faut fournir lors de la modification d’un système lorsque sa qualité interne freine l’évolution.
Et c’est justement pour cela qu’une application peut continuer à fonctionner correctement tout en devenant de plus en plus difficile à faire évoluer.
10 fonctionnalités plus tard, le système a complètement changé
Le début d’un projet est souvent simple.
Un MVP est créé.
Puis viennent de nouvelles exigences :
- intégration avec un CRM,
- paiements en ligne,
- panneau d’administration,
- application mobile,
- nouveaux rôles utilisateurs,
- reporting,
- automatisations,
- API,
- intégrations avec des services externes,
- nouvelles versions linguistiques.
Chaque changement, pris isolément, peut être justifié.
Le problème apparaît lorsque l’architecture n’a pas été conçue pour une telle direction d’évolution.
À ce moment-là, les nouvelles fonctionnalités ne s’ajoutent plus à une structure stable.
Elles s’ajoutent aux exceptions, aux contournements et aux compromis précédents.
Comment reconnaître qu’un système commence à vieillir ?
Il n’est pas nécessaire d’attendre une panne totale.
Les signaux d’alerte apparaissent bien plus tôt.
1. Une nouvelle fonctionnalité prend de plus en plus de temps
Autrefois, une fonctionnalité prenait quelques jours. Aujourd’hui, un changement similaire demande plusieurs semaines.
Cela ne signifie pas nécessairement que l’équipe travaille plus lentement.
Cela peut signifier qu’une part de plus en plus grande du temps est consacrée à comprendre le système existant et à le protéger des effets du changement.
2. Chaque changement déclenche un effet domino
La modification d’un module provoque des problèmes dans plusieurs autres endroits.
C’est le signe que les composants sont trop fortement couplés ou que les frontières de responsabilité entre eux ont été mal définies.
3. Les tests sont principalement manuels
Si chaque changement important nécessite une vérification manuelle de dizaines de fonctionnalités, le coût de mise en production augmente.
Le problème n’est pas l’absence d’automatisation en soi.
Le problème est l’impossibilité d’obtenir rapidement une information fiable sur le fait qu’un changement a cassé quelque chose ou non.
4. L’équipe hésite à toucher certaines parties du système
C’est un indicateur très concret.
S’il existe des modules que les développeurs évitent parce que "personne ne sait exactement ce qui se passera après une modification", le risque technique est déjà un coût réel pour l’entreprise.
5. Le système dépend de technologies obsolètes
Un ancien framework ne pose pas en soi un problème.
Le problème apparaît lorsque :
- il n’est plus maintenu,
- il est difficile de trouver des spécialistes,
- les dépendances ne peuvent pas être mises à jour en toute sécurité,
- l’environnement d’exécution est problématique,
- l’intégration avec de nouvelles solutions est compliquée.
À ce moment-là, la technologie commence à limiter les possibilités métier.
Faut-il toujours réécrire l’application de zéro ?
Non.
C’est l’une des erreurs les plus fréquentes dans l’approche des logiciels legacy.
Une réécriture complète peut se justifier, mais c’est une entreprise à haut risque.
Un ancien système contient souvent des dizaines ou des centaines de règles métier, d’exceptions et de comportements qui n’apparaissent pas dans la documentation. En le réécrivant de zéro, on peut très facilement créer un système technologiquement nouveau, mais incomplet sur le plan métier.
C’est pourquoi, dans de nombreux cas, une meilleure solution est la modernisation progressive.
Une partie du système reste active, tandis que les autres domaines sont remplacés progressivement par de nouveaux composants.
Cette approche est notamment connue sous le nom de patron Strangler Fig. Elle permet de moderniser le système étape par étape, d’apporter de la valeur plus tôt et de réduire le risque lié à une migration unique de l’ensemble de la solution.
Quand la modernisation a-t-elle du sens ?
Il vaut la peine d’y réfléchir lorsque :
- le système exécute toujours des processus métier importants,
- l’architecture permet d’extraire au moins une partie des fonctionnalités,
- les données peuvent être migrées ou intégrées de manière sûre,
- le problème concerne des zones précises et non toute la structure,
- l’application génère de la valeur et son remplacement complet serait risqué,
- le système peut être modernisé par étapes.
C’est une solution particulièrement adaptée aux systèmes qu’on ne peut tout simplement pas arrêter pendant plusieurs mois.
Quand la modernisation peut-elle ne pas avoir de sens ?
Il existe aussi des situations dans lesquelles continuer à sauver un ancien système n’est plus économiquement viable.
Par exemple lorsque :
- l’architecture est fondamentalement incompatible avec les exigences actuelles,
- les technologies clés ne sont plus prises en charge,
- le système ne dispose ni de tests fiables ni de documentation,
- la sécurité nécessite une refonte en profondeur,
- chaque changement important exige d’intervenir dans presque tout le système,
- il manque des personnes qui comprennent son fonctionnement,
- les coûts de maintenance et de développement dépassent la valeur de la poursuite de son utilisation.
Dans ce cas, il faut calculer non seulement le coût de la modernisation.
Il faut aussi calculer le coût de rester sur la solution actuelle.
L’application la plus chère n’est pas toujours celle qui coûte le plus à maintenir
On peut avoir un système dont la maintenance mensuelle coûte relativement peu.
Et pourtant, chaque nouvelle fonctionnalité coûte bien plus que ce qu’elle devrait.
C’est précisément pour cela que la simple facture d’hébergement, de serveur ou de support ne dit pas encore combien coûte la technologie.
Le vrai coût d’un système comprend aussi :
- le temps de développement,
- le temps de test,
- le coût des erreurs,
- le temps de déploiement,
- le coût des interruptions,
- difficulté de recrutement,
- risque de sécurité,
- coût de la perte de connaissances,
- retard des nouvelles fonctionnalités,
- limitations business résultant de la technologie.
À un certain moment, la technologie cesse d’être un outil au service de l’entreprise.
Elle commence à devenir une contrainte pour l’entreprise.
Comment aborder la décision ?
Avant qu’une décision « réécrivons tout » ne soit prise, il vaut la peine de réaliser un audit technique.
Il devrait couvrir au minimum :
L’architecture - comment le système est structuré et comment ses éléments communiquent.
Le code - la qualité, la complexité, la répétitivité et les zones particulièrement difficiles à maintenir.
Les dépendances - frameworks, bibliothèques, versions et leur support.
La sécurité - les vulnérabilités, la manière de gérer les accès et les risques liés aux composants obsolètes.
Les tests - le niveau d’automatisation et la possibilité d’introduire des changements en toute sécurité.
CI/CD - la manière de construire, tester et déployer l’application.
Les données - la structure de la base, les migrations, les intégrations et les dépendances.
Le monitoring - sait-on ce qui se passe avec le système après le déploiement.
Le processus de développement - combien coûte réellement la livraison d’une fonctionnalité supplémentaire.
Ce n’est qu’à partir de là qu’on peut envisager rationnellement trois scénarios :
- nous maintenons et faisons évoluer,
- nous modernisons par étapes,
- nous construisons un nouveau système.
Il n’existe pas de seule bonne réponse. En revanche, il existe une bonne manière d’y parvenir.
La technologie doit permettre la croissance, et non la bloquer
Une bonne architecture ne consiste pas à ce que le système paraisse moderne.
Elle consiste à pouvoir le faire évoluer quand l’entreprise en a besoin.
C’est pourquoi il vaut la peine d’examiner une application non seulement sous l’angle de son fonctionnement aujourd’hui.
Il faut également vérifier, combien coûtera l’ajout de fonctionnalités supplémentaires dans un an, deux ans ou cinq ans.
Car un système qui fonctionne, mais empêche une évolution fluide, peut être un problème bien plus grave qu’un système qui nécessite simplement une modernisation.
