Le Refactoring

La machine à café, c’est un peu un objet magique pour les développeurs. On peut y voir deux principales capacités. Elle provoque des résolutions de problèmes spontanées suite à des discussions proche de la machine. Et elle produit le café qui, une fois assimilé par le développeur, se transforme en d’innombrables lignes de code. Alors quand on possède un tel objet, on n’a pas envie de le casser. On voudra certainement l’améliorer, mais en le gardant fonctionnel. Tiens, ne commencerait-on pas à parler de refactoring ?

Avant d’entrer dans les détails, je vous propose de sortir un stylo et une feuille afin de vous poser la question suivante : qu’est-ce que le refactoring ? Faites couler l’encre, gravez votre définition dans les fibres du papier.

Définitions et fondamentaux

Le refactoring demande de la discipline et de l’apprentissage. Il existe des méthodologies, des principes et de multiples techniques. Ah bon, ce n’est pas juste tout refaire ? Non. On voit trop souvent ces fameux « chantiers » qui durent des mois, effectués en silo, sans visibilité et qui ont un résultat peu satisfaisant. Ils auront souvent duré bien plus longtemps que prévu, ou comporteront des régressions, ou seront abandonnés avant la fin. J’en ai vu et j’en vois malheureusement encore. J’en ai également fait, mais depuis, j’ai appris et je continue d’apprendre.

Aujourd’hui, j’ai envie de parler de ce qu’est le refactoring, de ses grands principes. Avant de se lancer dans ces grands chantiers, comprenons de quoi on parle. Je vais m’appuyer sur les définitions de Martin Fowler. Si vous ne le connaissez pas, c’est un des grands noms quand on parle de refactoring. Je vous recommande son site et ses livres.

noun: a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.

verb: to restructure software by applying a series of refactorings without changing its observable behavior.

Je vois plusieurs fondamentaux dans ces définitions. C’est bien plus que « tout ré-écrire » ou même que « ré-écrire pour améliorer » (déjà plus précis, mais encore trop simpliste).

Faire du refactoring, c’est conserver le même comportement. Ne pas casser l’existant. Si on change le comportement, ce n’est plus du refactoring. On sépare le refactoring des évolutions et corrections de bugs. Dans le cycle du TDD, il y a une étape dédiée pour le refactoring ; ce n’est pas pendant qu’on écrit le test ni pendant qu’on fait émerger une solution. Lorsque l’on fait du refactoring sur la machine à café, on veut qu’elle continue à faire du café lorsque l’on a terminé. On ne veut pas qu’elle fasse un thé, ni un tiramisu. Et on veut encore moins qu’elle soit en panne.

Faire du refactoring, c’est avancer par petites étapes. On enchaîne une série d’améliorations, on évite de vouloir tout changer d’un coup. Ce sont des petites étapes que l’on peut partager régulièrement. C’est à dire les rendre disponibles aux autres, les committer, les rapatrier sur la branche principale. Ainsi, on peut s’arrêter à tout moment. Si soudainement on doit faire quelque chose de plus prioritaire ou partir en vacances, le projet est toujours dans un bon état et nos petites améliorations seront en plus intégrées. Dans l’hypothèse où les développeurs tirent leurs super-pouvoirs du café, si pendant un mois la machine est en chantier, donc inutilisable, ça posera des problèmes.

Faire du refactoring dans le but d’améliorer la compréhension et de diminuer le coût du changement. On peut vouloir rendre le code plus lisible, avec une intention plus claire, un métier mieux projeté. L’amélioration continue est importante. On peut vouloir également rendre le changement plus facile, donc moins couteux. Ré-écrire uniquement pour le plaisir du développeur d’intégrer le dernier framework X-2000 est peut-être une moins bonne raison. Notre machine à café a besoin d’un refactoring, car elle ne prend en charge qu’un seul type de dosette très précis.

Je pense qu’il est important de prendre conscience de ces fondamentaux et d’être dans cet état d’esprit afin d’améliorer son approche du refactoring. Bien sûr, il reste du chemin ensuite, ce n’est que le début du voyage, mais c’est une étape essentielle.

Aller plus loin

Pour continuer d’approfondir le refactoring, on peut regarder du côté de la détection de code smells, de l’apprentissage des techniques de refactoring, de méthodes pour structurer un refactoring, ou encore de l’art de tester du code legacy (casser des dépendances, introduire des tests, …). Oui, la liste est grande, ce n’est pas si simple. Et oui, il ne faut pas oublier les tests pour s’ajouter un filet de sécurité.

Quelques ressources autour du refactoring :

  • Martin Fowler. Une figure incontournable avec son le site refactoring.com et son livre Refactoring Improving the Design of Existing Code.
  • Michael Feathers. Une seconde figure incontournable, plus axée sur le code legacy avec son livre Working Effectively with Legacy Code.
  • Le site refactoring.guru listant techniques de refactoring et code smells.
  • Divers katas pour s’exercer comme le Gilded Rose, Tennis Game, Trivia, etc.
  • Ici même, avec le temps, via le tag #refactoring.

Seconde édition

Vous avez toujours le bout de papier avec votre première définition ? Reprenez-le. Je vous propose d’écrire une nouvelle fois ce que représente le refactoring pour vous pour terminer. Au dos de la feuille ou sans relire les définitions a minima.

Amusez-vous à comparer les trois définitions maintenant. Et si le cœur vous en dit, partagez-moi vos écrits :)