J’ai récemment eu une discussion sur le refactor (aussi appelé Refactorisation ou Réingénierie logicielle) avec Rafaël, Directeur Produit chez Nexapp et Axify, où il cherchait à en savoir plus sur le travail de développeur. Plus précisément, comment justifier les refactor que nous effectuons lors du développement?
Ma réponse a été: Ça dépend…
Je sais je sais, ce n’est pas très satisfaisant comme réponse!
Cependant, le concept de refactor est assez large, donc difficile à regrouper sous une seule réponse. Prenons un moment pour parler des différents types de refactor, pourquoi ils sont pertinents et surtout, quand sont-ils pertinents?
Lisibilité et clarté du code
Un premier type de refactorisation a pour objectif d'augmenter la lisibilité et la clarté du code. On veut que ce dernier soit le plus facile à comprendre possible. Un développeur passe la grande majorité de son temps à lire plutôt qu'à écrire. Le ratio est d'environ 90% de lecture, contre 10% d'écriture. Il est donc pertinent de travailler à augmenter la vitesse de lecture lorsqu'une équipe souhaite augmenter sa vitesse de développement.
Quand est-il pertinent de travailler sur la lisibilité du code? Toujours!
Pendant le développement d'une fonctionnalité, il est important de faire l'effort de bien structurer le code, de bien nommer les variables et les fonctions, et de disposer de fichiers bien formatés. Plus tôt l'effort est fait, mieux se déroulera le développement, et moins importantes seront les refactorisations subséquentes.
Lorsque notre fonctionnalité nécessite de modifier du code existant, il arrive que ce dernier ait manqué un peu d'amour. Le refactor devient alors pertinent pour clarifier ce que fait le code, développer la connaissance nécessaire pour réaliser le travail, ainsi que rendre le code plus simple pour ceux qui passeront par là ensuite.
Recommandation : Lorsqu'un refactor pourrait faciliter votre travail, créez une branche à côté des fonctionnalités avec seulement la refactorisation. Ouvrez une "merge request" avec ces changements et commencez votre fonctionnalité sur ces changements. Séparer le refactor et la fonctionnalité facilitera le travail de vos pairs lors de la révision de votre code.
Nouvelle architecture logicielle
Lorsque je discutais avec Rafaël, il me faisait part d'histoires de développeurs qui mentionnaient de gros refactor nécessitant plusieurs jours de travail. Ce type de changement est rarement uniquement pour augmenter la lisibilité. Généralement, cela survient lorsque l'architecture actuelle ne répond plus aux nouveaux besoins du produit. Une nouvelle fonctionnalité? Un changement rapide de la vision du produit? Il existe plusieurs raisons.
Il est important de comprendre que le besoin de changer l'architecture ne provient pas d'une mauvaise décision ou d'une mauvaise implémentation. Il faut garder à l'esprit que l'équipe qui a mis en place l'architecture initiale l'a fait au meilleur de ses connaissances techniques, ainsi que du produit à réaliser. Nous construisons des softwares. Comme le nom l'indique, c'est soft, souple. Il faut s'attendre à ce que le code soit malléable et en constante évolution.
Trop souvent, cette réalité du développement logiciel n'est pas expliquée aux clients. Développer une application est extrêmement différent de construire un pont. Construire un pont est compliqué, mais il n'y a pas d'inconnu. Le plan est final et sera mis en œuvre de la même façon, peu importe le nombre de fois que le plan sera construit. Il n'est pas possible de dire en cours de construction : "Ah, finalement, j'aimerais avoir une voie de plus dans chaque direction !". Si construire un pont est compliqué, développer une application est quelque chose de complexe. Pour une même fonctionnalité, il existe mille façons de l'implémenter. De plus, il est possible, et même fréquent, que le client apporte des changements en cours de route!
Il faut donc prendre le temps d'expliquer aux clients et aux gestionnaires que des changements dans le code existant ne signifient pas nécessairement que le travail a mal été fait initialement.
La règle des Scouts pour la refactorisation
Au cours du développement d'un produit, il arrive que les conventions d'équipe changent. Que ce soit pour le nommage, la structuration des fichiers ou la communication entre deux systèmes, il y aura toujours des changements dans la façon de faire les choses. Lorsque cela se produit, il faut faire attention à la manière dont ces changements sont appliqués. Appliquer une décision à l'ensemble du projet peut avoir de grandes répercussions. Selon la taille de ce dernier, un changement de convention peut nécessiter plusieurs jours de travail avant que l'ensemble du projet soit à jour. C'est dans ces situations que la gestion, et même le client, commence à se poser des questions. Ce genre de refactor est extrêmement difficile à expliquer et à justifier. Comment faire pour éviter que cela se produise?
Une pratique intéressante est l'une des règles des Scouts : toujours laisser l'endroit un peu plus propre qu'à notre arrivée. Cela signifie qu'un refactor devrait être appliqué uniquement dans la partie du code sur laquelle l'équipe travaille.
Prenons comme exemple une équipe qui prend la décision d'abstraire une librairie pour éventuellement s'en départir. Le premier réflexe serait de faire le travail d'un seul coup! Cependant, celle-ci est utilisée partout dans l'application, donc représente un changement colossal. Une semaine de travail complète. Que va-t-il se passer à court terme avec la vélocité de l'équipe, si le changement est fait d'un seul coup? Elle va diminuer! Et c'est à ce moment que le client commence à poser des questions.
Et si, en plus de la diminution de la vélocité, une erreur est introduite dans une partie de l'application qui n'est plus en développement depuis des mois. Que va-t-il se passer? Plus de questions de la part du client!
Effectuer le changement d'un seul coup a beaucoup d'impact sur le développement du produit, comme vous pouvez le constater. Utiliser la règle du scout et appliquer le changement seulement si on a à faire dans cette partie du code résout ces problèmes. Au fur et à mesure que le développement progresse, notre abstraction de librairie continuera d'avancer. Ça peut prendre 6 mois, 1 an, 2 ans! L'objectif est d'augmenter constamment la qualité du code sans causer d'impact indésirable. En appliquant cette règle, il n'est donc plus nécessaire de justifier ce type de travail auprès du client.
Comment changer son vocabulaire pour mieux apporter la refactorisation
Le terme refactor ne signifie pas grand-chose pour ceux qui ne sont pas dans notre domaine. Il peut même faire peur pour certaines personnes! Il suffit d'une mauvaise expérience avec une équipe de développeurs et le mot devient un "red flag" pour le client. Un changement dans le discours des développeurs peut grandement améliorer la communication avec l'équipe produit et le client. Il s'agit de remplacer le mot "refactor" dans notre vocabulaire par "préparation du terrain".
Avant de commencer une fonctionnalité, nous devons examiner l'état des lieux, poser notre analyse, puis préparer le terrain pour bien faire notre travail. C'est une étape essentielle dans le développement logiciel pour obtenir un produit de qualité qui évoluera bien dans le temps. Cela fait partie de notre travail en tant que développeur logiciel et nous ne devrions pas avoir à le justifier, de la même manière qu'un électricien ne devrait pas avoir à justifier le temps qu'il va prendre pour aller couper le courant avant de faire son travail.
En changeant notre vocabulaire pour dire que l'on prépare le terrain, cela nous amène à nous poser des questions intéressantes sur la refactorisation que l'on souhaite effectuer.
- Est-il pertinent de préparer le terrain après avoir réalisé une tâche?
- Est-il pertinent de préparer le terrain pour un travail à effectuer dans trois mois?
- Est-il nécessaire de préparer un terrain de la taille d'un terrain de football pour une fonctionnalité aussi petite qu'un cabanon?
Cette façon de communiquer apporte une certaine structure quant à la taille, au moment et à la pertinence d'une refactorisation.
Je termine avec une citation de Martin Fowler provenant de son livre Refactoring: Improving the Design of Existing Code :
Les articles en vedette
Pair et mob programming : pour la sécurité psychologique!
Comment découper votre travail pour maximiser l'efficacité en développement logiciel
Femmes en tech : surmonter les défis, briser les stéréotypes
Soyez les premiers au courant des derniers articles publiés
Abonnez-vous à l’infolettre pour ne jamais rater une nouvelle publication de notre blogue et toutes nos nouvelles.