Le refactoring est une activité quotidienne pour les développeurs, pourtant souvent perçue comme complexe. D'après les statistiques sur mon projet passé, un mauvais refactoring se classe 6e parmi les causes d’introduction de bugs les plus fréquentes. Cependant, ne pas refactorer n'est pas une solution, car c'est un processus essentiel pour maintenir la qualité et l’évolutivité d’un projet logiciel. Au fil du temps, la dette technique s'accumule, ce qui ralentit le développement, démotive les intervenants du projet, impacte la stabilité des livrables et freine la mise à l’échelle d'un projet. Le refactoring est un outil indispensable pour prévenir l’augmentation de la dette mais également pour la réduire dans les cas les plus extrêmes.
J'ai récemment assisté à des conférences lors de l’évenement Mobilis in Mobile et suivi une formation sur ce thème. J'aimerais partager les points clés sur le refactoring et comment le maîtriser. Le sujet se découpe en trois articles, voici le premier, il concerne la dette technique
Le concept de dette technique représente les compromis réalisés lors du développement, souvent pour des raisons de deadline ou de budget, qui finissent par nuire à la qualité du code. Ces compromis peuvent ralentir les futurs développements et rendre le code plus difficile à maintenir.
Puisque le refactoring est une solution apportée pour combattre la dette technique on est en droit de se demander ce qui apporte cette dette sur un projet. En voici quelques causes courantes:
Lorsque vous corrigez un bug, vous avez deux options : le traiter à la racine ou le contourner. Si choisir la solution rapide peut sembler tentant, cela revient à balayer la poussière sous le tapis. Le problème n'est pas résolu, simplement dissimulé, et finit toujours par réapparaître, souvent au pire moment, compliquant les futures modifications du code. Tout comme changer ce tapis disperserait la poussière dans toute la pièce, toucher au code de contournent d’un bug peut propager des problèmes à travers le projet.
Les POCs sont souvent créés pour valider une idée rapidement, mais si on commence à développer une application basée sur un POC sans reprendre les fondations correctement, cela génère de la dette technique. C’est comme construire une maison en paille et ajouter des briques par-dessus : la structure s'effondrera.
Dans un projet de longue durée, les développeurs expérimentés sont souvent les gardiens de la qualité du code et des standards de développement. Ils possèdent une compréhension approfondie des parties les plus complexes et parfois mystérieuses du projet. Grâce à leur expérience, ils savent comment résoudre rapidement certains bugs, car ils connaissent bien l’historique du produit et les problèmes récurrents. Lorsqu’ils quittent le projet, ils emportent avec eux un savoir précieux non documenté qui devient de la dette pour l’équipe restante.
C’est un peu comme dans une maison où les anciens occupants maîtrisent le bon coup de poignet pour fermer une porte capricieuse. Quand ils partent, les nouveaux habitants, perdus face à cette porte qui refuse de se fermer, se retrouvent obligés de la réparer, engendrant des frais imprévus.
Il arrive qu'une fonctionnalité soit développée sans réelle certitude qu'elle répondra aux besoins des utilisateurs, ou bien qu'elle ait été utile un temps avant d'être progressivement abandonnée après une mise à jour. Si les décideurs et les développeurs la laissent de côté sans la retirer, elle finit par créer de la dette technique, simplement en restant dans le code. Tandis que le reste du projet évolue et s’améliore, cette fonctionnalité reste figée, accumulant des risques. Avec le temps, elle peut devenir une cible facile pour les vulnérabilités, offrant potentiellement aux hackers une porte dérobée dans votre application.
C’est un peu comme si vous laissiez une pièce inutilisée dans votre maison sans jamais y faire le ménage : au fil du temps, cette pièce devient un terrain fertile pour les nuisibles.
Le simple fait que le temps passe crée de la dette technique, car les technologies évoluent, votre connaissance s’affine, les méthodes de développement progressent, et le code devient obsolète. Au fil des versions, les librairie déprécient certaines fonctions pour en introduire de plus performantes et compatibles avec les nouvelles technologies. Même un code impeccable à l'origine peut devenir problématique si des changements ne sont pas apportés régulièrement pour le mettre à jour.
Imaginez qu'en 1980, vous achetez le meilleur magnétoscope du marché, convaincu qu'il vous servira à vie. Mais en 2024, vous réalisez qu'il est devenu totalement inutile : plus aucun film ne sort en VHS. Vous n'avez plus le choix, il faut passer à Netflix. C'est exactement ce qui arrive à votre code quand il n'est pas régulièrement mis à jour.
Lors du développement d'un logiciel, on tente d'anticiper le futur pour maximiser son évolutivité, en alignant la vision des décideurs, leurs enjeux et leurs besoins. On construit ainsi les fondations du projet en fonction de cet avenir prévu. Mais si la stratégie change en cours de route, ces fondations deviennent obsolètes, créant ainsi de la dette technique.
Imaginez que vous construisez une maison avec une déco futuriste, murs blancs laqués et fils bien cachés. Mais juste avant d'emménager, vous réalisez que vous préférez finalement un style industriel avec tuyaux apparents et murs en béton brut. Votre maison est fonctionnelle, mais le décalage entre les deux styles crée une incohérence — c'est de la dette technique dans le monde du développement.
Les développeurs s’appuient sur une stratégie technique qu’ils estiment être la meilleure. Cependant, si cette vision n’est pas documentée ou évolue au fil du temps, des divergences apparaissent. Il arrive aussi que toute l’équipe ne suive pas la même approche. Des différences dans l'implémentation de code, même minimes, finissent par rendre le code difficile à maintenir et à faire évoluer.
Imaginez deux artisans posant un plancher dans votre salon. L'un place les planches dans un sens, l'autre dans l'autre sens. Au milieu, ça ne colle pas. Vous devrez alors choisir : retirer le travail de l'un, de l'autre, ou créer un compromis pour relier les deux. C'est exactement ce qui se passe quand des développeurs suivent des approches différentes dans un projet.
La théorie de la fenêtre cassée s'applique aussi en développement. « Si une vitre est cassée et n’est pas réparée, toutes les autres vitres connaîtront bientôt le même sort ». Si un projet accumule trop de dette technique, les développeurs peuvent perdre leur motivation à produire du code de qualité, ce qui entraîne encore plus de dette.
La dette technique est inévitable, mais il existe plusieurs stratégies pour la limiter efficacement.
Ma méthode préférée pour évaluer la santé d'un projet est d'analyser ses bugs. Ne vous limitez pas à les corriger, mais prenez le temps d'en comprendre l'origine. Cela vous permettra de mettre en place des solutions préventives. Plus vous étudiez un bug, plus vous êtes à même de le corriger à la source et d'éviter qu'il ne réapparaisse.
Écrivez vos standards techniques. Cela vous permettra non seulement de prendre du recul sur votre stratégie, mais surtout d'aligner toute l'équipe sur les meilleures pratiques adaptées au projet. Ces standards doivent être mis à jour si nécessaire, couvrant aussi bien la stratégie globale que les détails spécifiques du projet.
Les standards ne seront pas suffisants. Il est essentiel de former les développeurs aux bonnes pratiques et de les sensibiliser aux standards en place. Cela est particulièrement crucial lors de l'arrivée de nouveaux membres dans l'équipe.
Il est important de rappeler régulièrement aux développeurs pourquoi il est nécessaire de suivre les bonnes pratiques. Cela permet de maintenir un haut niveau de qualité dans le projet. Le “pourquoi” est un élément de contexte important pour l’adoption d’une pratique.
Réservez un créneau chaque semaine pour améliorer la qualité de votre projet. Cela permet de compenser la dette technique accumulée et de la réduire progressivement. Utilisez ce temps pour appliquer les autres conseils évoqués dans cet article.
Vous avez sûrement déjà entendu cette citation célèbre d'Oncle Bob : “Laissez le code plus propre que vous ne l’avez trouvé.” Inspirée des scouts, cette règle simple mais puissante, appliquée au quotidien, peut significativement réduire votre dette technique.
Bien souvent cela consiste à faire de tout petits refactoring.
C’est tout l’objet de cette série d’articles, lorsque vous identifiez une opportunité de refactoring qui pourrait améliorer la structure du code, n'hésitez pas à l'entreprendre, même si cela nécessite un investissement en temps. Cela évitera que la dette technique ne s'accumule.
Dans les prochains articles, nous verrons comment bien exécuter le geste difficile du refactoring et convaincre l'équipe produit d'y investir du temps.