logo le blog invivoo blanc

Refactoring d’un projet legacy : retour d’expérience

22 mai 2018 | Java | 0 comments

Le CTO de Vidressing, Hervé Lourdin, a présenté lors de la conférence un “CTO paie toujours ses dettes”, à Devoxx son expérience sur le refactoring d’un projet legacy.

Au cours de la présentation, il nous raconte comment lui et son équipe de développement en sont arrivés au besoin de mener un projet de refactoring important et la manière dont ils s’y sont pris pour y arriver.

Videdressing est une plateforme communautaire permettant la vente d’articles entre les membres. 1 000 000 de membres, 300 000 vendeurs et plus d’1 000 000 d’articles : au regard de ces chiffres, on peut considérer que le business a du succès.

 

Pourquoi un projet de refactoring ?

En tant que plateforme de commerce, ils sont régulièrement amenés à introduire le support de nouveaux moyens de paiement. C’est, d’ailleurs, au cours de l’introduction d’un nouveau moyen de paiement qui s’est assez mal déroulé que l’équipe de développement a pris conscience de la nécessité de mener un important refactoring de l’existant. Le speaker a identifié quatre principaux obstacles à l’évolutivité de leur plateforme qu’il appellera « quatre cavaliers de l’apocalypse technique ».

Une complexité injustifiée

Un code complexe demande beaucoup d’effort de compréhension et son évolution en exige encore plus. De plus, la mauvaise interprétation ou l’oubli d’un détail conduit à l’introduction de régressions pas facilement détectables. La complexification du code peut être le fait d’une mauvaise implémentation, d’une implémentation d’une mauvaise spécification métier, la somme des deux ou finalement l’implémentation d’une fonctionnalité intrinsèquement complexe. Toutefois, quel que soit la raison de la complexité, il existe des solutions pour en venir à bout.

Bugs fréquents

L’apparition fréquente de bugs est le signe de la perte de la maitrise du comportement des fonctionnalités implémentées. Cela a pour conséquence d’orienter une grosse partie des efforts sur la correction de ces bugs, au dépend des évolution métier ou techniques prévues.

Obsolescence technique de la plateforme

Le gros des efforts étant absorbé par les problèmes liés à la complexité de l’application, ils ne disposent pas de suffisamment de temps pour faire des évolutions de framework, ce qui a conduit à l’obsolescence technique de la plateforme. Il est donc impossible de bénéficier des avantages, souvent considérables, apportés par les derniers framework. Enfin, il est très compliqué de recruter de bons développeurs en leur mentionnant une stack technique vielle ou vieillissante.

L’impact des « héros »

La présence de « héros », ces rares développeurs dans une équipe qui maitrisent parfaitement la plateforme, était aussi source de problème. Ces derniers passaient leur temps à régler les problèmes créés par les autres, ce qui peut paraître à première vue comme un atout pour l’équipe. Mais le revers de la médaille est que leurs actions ne donnent pas aux autres développeurs l’opportunité de monter suffisamment en compétence. Et si la situation perdure, les héros seront à bout de souffle.

Face à ces obstacles, il était donc devenu clair pour les développeurs que des actions importantes devaient être menées afin que les développements soient fiabilisés et soient réalisés dans des temps raisonnables. Constat fait, ils devaient à présent en faire part aux autres intervenants du projet.

Communication sur le projet de refactoring

En tant que CTO, il rencontre régulièrement les dirigeants de l’entreprise et peut évoquer avec eux les sujets importants à son niveau. Il a donc été amené à leur présenter le sujet de la dette technique et la nécessite de la réduire via du refactoring en évoquant les obstacles des « quatre cavaliers de l’apocalypse technique ». Evoquer l’impact financier des conséquences de ces obstacles est très important car c’est un indicateur très parlant à l’équipe dirigeante.

 

Comment attaquer le projet de refactoring

Avant de travailler sur un projet de refactoring, il est tout d’abord important de commencer par comprendre l’existant. Puis, en s’assurant que ce qui est attendu du système par les équipes produit est bien ce qui est implémenté.

La vérité n’est pas dans le code

À la suite de divergences entre les visions qu’ont les équipes produit du système et celle que les développeurs voyaient dans le code, ils ont décidé de fixer comme premier objectif de produire une spécification du fonctionnement normal du système.

Nouvelles spécifications partagées et nouvelle plateforme de gestion des ordres

La production d’une nouvelle spécification du fonctionnement normal de la gestion des ordres a donc été faite à partir des avis de tous les intervenants et de l’analyse de tout existant, document ou code. Cette spécification était le premier livrable du projet, elle était utilisée comme référence pour communiquer pour tous les intervenants du projet.

L’analyse de la spécification leur a permis de conclure que le système de paiement et de gestion des ordres était l’épine dorsale de la plateforme de Videdressing. Il fallait donc commencer par sa refonte. L’aspect communautaire du business de la startup impliquait des workflows de passage d’ordre et de paiements différents de ceux d’un site de commerce classique. C’est pour cette raison qu’ils ont décidé d’adresser la refonte des workflows de ces systèmes à une société spécialisée dans ce domaine.

Décisions difficiles

Pour la suite, ils ont du prendre des décisions difficiles pour la mise en œuvre du refactoring :

  • Annuler ou reporter d’autres évolutions qui étaient planifiées,
  • Mobiliser une équipe, sur une période de 9 mois, pour mener le refactoring et cesser les corrections de bugs sur le système existant,
  • Durant le refactoring, accepter de produire des livrables avec les fonctionnalités minimales pour les améliorer ultérieurement.

Et une fois de plus, il a fallu avoir l’adhésion des autres intervenants du projet à ces décisions.

Plan de du refactoring

La roadmap consistait à faire migrer les moyens de paiement existants au fur et à mesure vers la nouvelle.

Des principes ont été mis en place pour mener le refactoring ainsi que des pratiques pour les respecter :

  • Limiter la taille des livrables pour livrer le plus rapidement possible en production,
  • L’usage du « feature flipping » pour pouvoir désactiver facilement en production les livrables du refactoring lorsqu’ils posent des problèmes.

 

Amélioration des processus

Le projet de refactoring a aussi été l’occasion d’améliorer le processus de développement sur différents aspects.

Méthodologie

  • Au niveau de l’équipe produit sur la priorisation et la traduction des besoins en user stories,
  • Au niveau de la mise en visibilité des processus en cours,
  • Mesures pour refléter l’usage des fonctionnalités de la plateforme par les utilisateurs et réagir en conséquence si nécessaire.

Développement

  • Rendre systématique les revues de code.

Devops

  • Packaging des environnements des développements dans Docker,
  • Possibilité de déployer immédiatement toute feature développée en vue de tests.

Résistance aux solutions legacy

Certains collègues habitués à la plateforme legacy vont vouloir, au détriment de la nouvelle, continuer à faire les évolutions sur l’ancienne. Ils voudront s’accrocher aux vieilles pratiques que le reste de l’équipe a mis tant d’effort à faire évoluer. Il est important d’identifier les coéquipiers dans cette posture et d’essayer de les raisonner. Sinon, prendre ses distances avec leur démarche en privilégiant les nouvelles pratiques autant que possible afin de produire de meilleurs résultats de cette manière.

 

Résultats du refactoring et leçons à retenir

Résultats

  • Ils ont réussi avec le temps à faire passer presque tous les ordres sur la nouvelle plateforme,
  • La nouvelle plateforme n’a presque pas de bugs. Plus facile d’investiguer et de corriger les rares soucis,
  • Impact positif perceptible au niveau des interactions du service clientèle,
  • Existence d’un document de référence sur la gestion des ordres et paiement compréhensible par tous les intervenants du projet, et plus uniquement par les développeurs.

Erreurs retenues

  • Tarder à informer les dirigeants sur l’impact de la dette technique,
  • Trop de temps et d’énergie consacrés à fixer des bugs plutôt que de lancer le projet de refactoring,
  • Absence de document de référence partagé par tous les intervenants sur le fonctionnement du système.

Autres leçons retenues

  • Certains collègues vont malheureusement continuer à faire évoluer le système legacy. Il faut en conséquence continuer à agir pour limiter l’impact de leurs actions,
  • Le « mob programming »  peut s’avérer approprié durant les phases de développement délicates,
  • Ne jamais délaisser les revues de code.

Conclusion

C’était très intéressant d’écouter un CTO partager une telle expérience. Si entre développeurs on a tendance à critiquer ces systèmes pour les difficultés qu’ils peuvent causer, il ne faudrait pas oublier que nous travaillons dans un cadre plus large, et que ces difficultés doivent être partagées avec le product owner et les autres intervenants du projet. L’expérience du speaker montre que les dirigeants peuvent être à l’écoute et être favorables à un projet de refonte lorsqu’on arrive à leur expliquer avec de bons arguments l’impact négatif de la dette technique sur l’ensemble du projet. Et si toutes les parties se mettent d’accord pour mener à bien la refonte, toute le monde en ressortira gagnant.

Ressources