Lire 50 lignes de code ou utiliser l'Extract Method Refactoring ? - L'avis de Derek Comartin
Dans le monde du développement logiciel, le remaniement est essentiel. L'une des techniques les plus courantes et les plus encouragées est l'extraction de méthodes (Extract Method Refactoring), qui consiste à décomposer un grand fragment de code en méthodes plus petites et réutilisables afin d'améliorer la lisibilité et la réutilisation. Bien que cela semble idéal en théorie, Derek Comartin, dans sa vidéo "I'd rather read 50 lines than Extract Method Refactoring", offre un point de vue neuf et critique.
Cet article présente la décomposition de Derek sur le refactoring des méthodes d'extraction, en offrant un contexte réel et des conseils pratiques. Nous suivrons son raisonnement exact et la structure de son code pendant qu'il nous explique quand et comment appliquer le refactoring par extraction, ainsi que les détails de sa mise en œuvre et ses inconvénients potentiels.
L'exemple : Inscription d'un utilisateur dans un système de discussion en ligne
Au début de la vidéo, Derek présente un exemple : une fonction d'inscription pour un système de chat. Il s'agit d'un bloc de code compact mais réaliste d'environ 50 lignes qui exécute plusieurs tâches :
-
Vérifie que le nom d'utilisateur n'est pas vide
-
Vérifie si le nom d'utilisateur est déjà pris
-
Traite les chaînes à accès limité par l'âge
-
Enregistre le nouvel objet utilisateur
- Envoi d'un courriel avec un lien d'activation
Ce code se trouve dans une fonction et, à première vue, il peut sembler être un bon candidat pour une refonte de méthode d'extraction. Mais comme le souligne Derek, refondre aveuglément sans en comprendre l'impact peut en fait nuire à la clarté.
Débuter avec le refactoring : Sélectionner une méthode d'extraction
Derek commence comme le font de nombreux développeurs, en divisant le fragment de code en plusieurs petits morceaux. Il montre comment sélectionner la méthode d'extraction par le biais du menu contextuel ou d'un raccourci clavier dans la plupart des IDE ou des éditeurs de code.
Il extrait :
-
validateUsername pour vérifier que le nom d'utilisateur n'est pas vide
-
existingSignUpNotActivated pour vérifier la présence d'un compte non activé
-
validateExistingUser pour gérer toutes les vérifications relatives aux utilisateurs existants
-
filterAgeRestrictedChannels pour traiter les chaînes destinées aux utilisateurs de moins de 18 ans
- sendEmail pour envoyer l'e-mail de bienvenue
Il donne à chaque nouvelle fonction un nom significatif, ce qui est l'un des principaux conseils souvent préconisés dans les pratiques de code propre. Mais au fur et à mesure qu'il parcourt ces versions modifiées, Derek commence à relever des failles dans la logique, non pas dans les fonctionnalités, mais dans la lisibilité et le flux de contrôle.
Enjeu 1 : Détails cachés de l'implémentation
L'un des premiers signaux d'alerte que Derek met en évidence est que les détails de l'implémentation sont désormais cachés derrière des méthodes extraites.
Par exemple, les méthodes validateUsername et validateExistingUser lancent des exceptions. Mais en tant que développeur lisant le code remanié, vous n'en auriez aucune idée si vous n'aviez pas accès à leurs parties internes.
Ce type de remaniement peut masquer la logique de contrôle, ce qui entraîne des bogues ou des validations manquées. La portée et le flux ne sont plus évidents. Au lieu de rendre le code plus clair, vous créez un labyrinthe d'abstractions où les effets secondaires tels que les exceptions ou les variables modifiées ne sont plus visibles dans la forme où la logique a été écrite à l'origine.
Edition 2 : Indirection et extraits enchaînés
Ensuite, Derek souligne le problème de l'indirection, lorsqu'une méthode d'extraction en appelle une autre, et ainsi de suite. Il montre comment la méthode validateExistingUser est elle-même composée de existingSignUpNotActivated.
Vous ne lisez plus un simple bloc de code descendant. Vous passez d'une méthode à l'autre, d'un fichier à l'autre et d'une classe à l'autre juste pour suivre ce qui se passe. Et si l'éditeur peut aider à naviguer dans ce flux, il devient un fardeau pour la charge cognitive du lecteur.
Cela devient encore plus difficile dans les grands systèmes où le remaniement s'étend sur plusieurs fichiers ou composants. Soudain, votre "code propre" semble plus difficile à suivre que les 50 lignes "désordonnées" d'origine.
Édition 3 : Variables locales et changement d'état
L'une des leçons les plus importantes de cette vidéo concerne la gestion des variables locales et la mutation d'état.
Derek met en avant la méthode filterAgeRestrictedChannels. Elle ne renvoie pas de résultat, mais modifie directement la liste de chaînes qui lui a été transmise. Cela signifie que vous modifiez l'état local à partir d'une méthode différente, et à moins d'inspecter la méthode de près, ce changement est caché.
Il s'agit de rompre avec l'idée qu'une fonction est soit une opération pure, soit qu'elle signale clairement qu'elle modifie des choses. Lorsque vous remplacez la logique par une nouvelle méthode qui ne renvoie pas de valeurs mais les modifie en interne, vous introduisez des risques et de la confusion.
L'alternative remaniée de Derek
Comment Derek fait-il pour remanier son ancien code ?
Il propose une approche beaucoup plus simple :
-
Conservez la logique explicite en ligne. La vérification initiale d'un nom d'utilisateur vide reste dans la méthode principale, car elle est facile à comprendre et n'encombre pas la base de code.
-
Renvoyer les résultats au lieu de les modifier. Au lieu de modifier la liste des chaînes, la fonction filterAgeAppropriateChannels renvoie désormais une liste filtrée. Cela permet de clarifier le flux de données et d'éviter les effets secondaires inattendus.
-
Utilisez des méthodes d'extraction simples et prévisibles. La seule autre méthode extraite est isExistingUserAlreadyActivated, qui renvoie clairement un booléen sans lancer d'exceptions. Elle encapsule la logique sans cacher les détails.
- Évitez les effets secondaires en ligne tels que l'envoi d'e-mails. Derek laisse la logique de l'e-mail en place pour la démonstration, mais suggère que dans un système réel, elle devrait être gérée via un événement dans un processus ou un fil séparé - et non quelque chose de directement lié à la soumission du formulaire de l'utilisateur.
Au total, Derek n'utilise que deux méthodes d'extraction et laisse le reste de la logique en ligne, car elle est plus facile à lire, à raisonner et à contrôler.
Conseils finaux sur la refonte des méthodes d'extraction
La vidéo de Derek nous donne quelques conseils pratiques pour utiliser efficacement le refactoring par méthode d'extraction :
-
Utilisez des noms significatifs qui décrivent exactement ce que fait la méthode.
-
Évitez les effets secondaires tels que la mutation d'état ou le lancement d'exceptions, à moins qu'ils ne soient évidents.
-
Renvoyer des valeurs au lieu de modifier les paramètres d'entrée.
-
Ne cachez pas la logique derrière de multiples couches d'abstraction.
- Si une méthode semble lisible dans sa forme originale, ne la transformez pas en plusieurs fonctions juste pour le plaisir de la refactorisation.
Parfois, la meilleure abstraction est l'absence d'abstraction, surtout lorsqu'elle se fait au détriment de la clarté et de la connaissance du champ d'application.
Conclusion
L'approche de Derek Comartin remet en question l'idée selon laquelle le remaniement améliore toujours le code. Dans le cas du remaniement des méthodes d'extraction, le moins est souvent le plus. Au lieu d'utiliser à outrance la méthode Select Extract pour hacher votre logique, évaluez ce qui apporte de la valeur ajoutée, ce qui facilite la compréhension de votre code et ce qui cache des détails importants.
Avec des exemples clairs et un aperçu direct du code réel, Derek montre dans sa vidéo que parfois 50 lignes dans une seule méthode, lue de haut en bas comme une histoire, valent mieux que dix méthodes plus petites réparties dans votre base de code.
Si vous avez déjà eu recours à un raccourci clavier pour créer une nouvelle méthode, n'oubliez pas le conseil de Derek : faites une pause, évaluez et assurez-vous que le remaniement est utile au lecteur, et pas seulement à l'IDE.
