Les raisons qui poussent les équipes IT à retravailler leur code sont nombreuses. Parmi elles peut se glisser une complexité excessive qui rend le code difficile à comprendre et à modifier, ou une mauvaise architecture qui apporte rigidité et manque d’évolutivité. La dette technique, accumulée par des solutions « pansements » et des compromis, nécessite également un « refactoring de code » pour améliorer la qualité de ce « code legacy ». Eloise Schmittt, développeuse back-end chez Inside Group, nous éclaire sur cette démarche qui vise à améliorer la qualité, la maintenabilité et l’évolutivité du code, tout en nous prodiguant ses bonnes pratiques.
Peux-tu nous expliquer ta vision du refactoring de code ?
Le refactoring de code représente une part essentielle de la démarche Craftsmanship, que nous valorisons régulièrement chez Inside. Pour définir cette démarche de refactoring, nous nous basons sur deux ouvrages de référence. Le premier est le livre de Martin Fowler « Refactoring – Comment améliorer le code existant », qui décrit cette démarche comme « l’opération consistant à retravailler le code source d’un programme pour en améliorer la lisibilité et, par conséquent, la maintenance. Il ne s’agit pas seulement de le compléter ou d’en corriger des bugs, mais d’en améliorer la structure sans en altérer le fonctionnement ». Dans ce cadre, deux concepts sont indissociables : les tests et les « code smells », ces derniers désignant des mauvaises pratiques de conception logicielle qui mènent à des défauts. Le second ouvrage, de Michael Feathers, intitulé « Working Effectively with Legacy Code », traite des stratégies et techniques pour améliorer et maintenir en toute sécurité les systèmes logiciels existants afin de les rendre plus évolutifs et maintenables. Nous nous appuyons donc sur des théories éprouvées par des ingénieurs et mises en pratique depuis de nombreuses années ; c’est notre base !
Quels enjeux se cachent derrière le refactoring code ?
Chez Inside, nous identifions trois raisons principales : la lisibilité du code, la stabilité/fiabilité du code, et sa maintenabilité. Nous partons du principe que n’importe quel développeur (humain ou IA) peut écrire du code compréhensible par un ordinateur. En revanche, écrire du code compréhensible par un autre développeur demande des compétences plus élevées (Comme par exemple le Clean Code. Ainsi, un code lisible est plus facile à comprendre et à modifier, même par un développeur qui n’en est pas l’auteur. Cela permet d’implémenter plus rapidement de nouvelles fonctionnalités et facilite l’intégration d’un nouveau dev’ dans une équipe. Les tests sont un autre point essentiel dans le refactoring de code, car ils apportent fiabilité et stabilité. Ils permettent notamment de limiter les effets de bord et l’apparition de bugs en production. Les équipes gagnent ainsi du temps, et la satisfaction des clients est accrue. L’approche Test Driven Development (ou TDD) est idéale dans ce contexte, tout comme le recours aux tests d’intégrations (par exemple). Enfin, un code bien conçu est rapidement modifiable, ce qui assure un bon niveau de maintenabilité, rendant le projet plus véloce et moins couteux.
Quels sont tes conseils pour mettre en œuvre cette démarche de refactoring ?
Nous conseillons chez Inside de faire régulièrement du refactoring, dans une démarche d’amélioration continue et pas uniquement de débogage. Cela peut prendre la forme d’un renommage de certaines parties du code, qui peut constamment être amélioré. C’est donc un « chantier » quotidien, qui concerne toute l’équipe, et qui se fait par petits pas chaque jour. Il se peut que le chantier soit plus important en fonction du contexte, notamment avec du code legacy qui n’a pas été écrit pour être testable, avec de nombreuses dépendances. Heureusement, il existe de nombreuses méthodes pour que ce refactoring se passe au mieux selon les cas.
La première d’entre elles consiste à chercher et à repérer les « codes smells », c’est-à-dire les codes, méthodes et classes qui ont pris des proportions tellement gargantuesques qu’il est difficile de les gérer. En général, ils n’apparaissent pas immédiatement, mais s’accumulent au fil du temps, à mesure que le programme évolue (et surtout lorsque personne ne fait l’effort de les éradiquer). Il y a également le code provenant d’applications incomplètes ou incorrectes, ou encore les « dispensables », donc inutiles, dont l’absence rendrait le code plus propre, plus efficace et plus facile à comprendre. De manière générale, la présence de code smells est souvent le signe qu’une refactorisation est nécessaire. Voici un autre signe alarmant : quand le temps passé pour ajouter ou modifier une fonctionnalité est de plus en plus long.
Ainsi, plus le temps passe, plus la dette se cumule, et plus les temps de développement sont longs.
Une fois que le besoin de refactoring est bien identifié, je conseille de commencer par l’approval testing. Contrairement aux tests de pré-production traditionnels (unitaires, d’intégration, end-to-end) qui garantissent la pérennité d’une fonctionnalité spécifique, les tests d’approbation visent à faire un état des lieux du code (cette méthode se nomme également Golden Master). C’est donc une étape préparatoire au refactoring. Pour concevoir son golden master et être certain de valider toutes les conditions de la méthode refactorisée, je conseille de lancer un coverage (métrique qui mesure le pourcentage de lignes de code exécutées par les tests) sur son IDE (environnement de développement intégré). Quand le coverage atteint 100%, faire du mutation testing. La bonne approche est d’écrire une seule modification sur son code puis de relancer un approval testing pour s’assurer de l’attendu, avant de faire un commit de celle-ci (opération qui envoie les dernières modifications du code source au référentiel, faisant de cette modification une partie de la révision principale du référentiel). Et ainsi de suite, afin de s’assurer que tout ce que faisait le code avant l’opération soit encore fonctionnel après la modification, et d’identifier très rapidement l’arrivée éventuelle d’un nouveau bug. En ce qui concerne les méthodes elles-mêmes, je conseille (en plus des ouvrages cités plus haut) de visiter le site refactoring guru qui est une véritable mine d’or pour les développeurs et le refactoring code.
Comment Inside accompagne ses clients autour de la qualité de code ?
Précisons d’emblée que « faire du refactoring pour faire du refactoring » peut être contre productif. Comme dit l’adage : le mieux est l’ennemi du bien. C’est ce qui peut arriver lorsqu’une équipe manque d’expérience, en complexifiant un code ou en appliquant une méthode qui ne colle pas dans le contexte. Il existe par exemple une méthode « changer la valeur en référence », et une autre « changer la référence en valeur ». Et utiliser l’une à la place de l’autre ne va pas régler de problème, bien au contraire. Mais qu’il s’agisse d’un manque de séniorité d’une équipe IT, d’un POC qui passe trop vite en production ou d’un delivery qui s’allonge, d’une précipitation et d’un oubli de bonnes pratiques, ou même de la volonté d’implémenter la démarche DDD (Domain Driven Design) dans son organisation, Inside propose des audits et des accompagnements adaptés à chaque contexte.
Nous proposons par exemple Refactoring XPLORER : notre Serious Game sur la qualité du code et clean code, afin de sensibiliser aux notions de code smells et de refactoring, souvent mal perçues dans les équipes de développement. Pour aller plus loin, nous proposons des coachs craftsmanship, car les premiers refactorings de code peuvent « faire peur » ainsi qu’un accompagnement continu jusqu’à l’autonomie des équipes de développement. L’ampleur du chantier semble souvent plus importante qu’elle ne l’est, mais avec de bonnes pratiques, il ne faut surtout pas hésiter à se lancer.
Nous proposons en complément des accompagnements et de l’acculturation sur les démarches Accelerate et Agile car elles interviennent également dans la qualité du code délivré, s’inscrivant dans une démarche plus globale d’amélioration continue et de Less Rework.
Echangeons sur l’optimisation de vos démarches de refactoring de code !