TDD en action : refactoring
Repérage
● TDD en action– Découverte
– Refactoring
– Itératif incrémental
– Bases de données
– Développement Web
– Déploiement continu
Nous allons aborder ceci
Refactoring
● Définition● Théorie● Exemples● Exercice● Auto-évaluation
Refactoring
● En français vous pourrez trouver le terme « remaniement »
● Définition dans notre contexte logiciel
Modifier la structure interne d'une partie de code sans modifier son comportement observable
...donc :
● Le code change● La couverture fonctionnelle ne change pas● Les tests passent toujours
Gains attendus
● + simple● + évolutif● + performant● …● La « qualité » du code augmente
Qu'est qu'un code de qualité ?
● +simple, +évolutif, +performant ?● Les programmeurs et les clients ont-ils la même
réponse ?● Proposition:
Un code de qualité est un code pour lequel le coût d'ajout d'une nouvelle fonctionnalité reste stable
avec le temps
1.TEST 2.CODE
3.REFACTOR
● Le refactoring a lieu lorsque les tests passent● Le refactoring n'ajoute pas de fonctionnalité● Le refactoring concerne le code de production
et le code de test
1.TEST 2.CODE
3.REFACTOR
● Le refactoring consiste à améliorer le code● Une façon pour améliorer le code consiste à
supprimer le code dangereux● Vous entendrez parler de « dette technique »
Le refactoring consiste à diminuer la dette technique
● Qu'est ce que du code « dangereux »?– Duplication
– Couplage
– Valeurs magiques
– Commentaires (avez-vous envie de réagir à celui-ci ?)
– Conditionnel
– Longues classes ou méthodes
– Code obscur
– ...cherchez « code smells » sur Google
3.REFACTOR
● Connaissez les « code smells » qui vous aident● Essayez plusieurs smells pour trouver ceux qui
vous aident● Commencez par étudier les plus faciles
– Bad name
– Switch statement
– Primitive obsession
● Lorsque vous n'avez pas d'intuition d'amélioration, cherchez les smells qui vous ont déjà aidé
3.REFACTOR
3.REFACTOR
Un « code smell » est une opportunité, pas une règle ni une obligation de refactoring.
● Comment supprimer du code « dangereux »?– Introduire des « Design patterns »
● Création● Structures● Comportements
– Respecter les principes SOLID● Single responsability● Open/Closed● Liskov substitution● Interface segregation● Dependency inversion
3.REFACTOR
● Comment supprimer du code « dangereux »?
3.REFACTOR
● Une possibilité : piloter vos refactoring par de nouveaux tests
● Une possibilité : programmer par intention et laisser les tests existant réagir
● Une possibilité : faire les deux
3.REFACTOR
2 exemples
● Supprimer un smell « God class »
● Supprimer un smell « Comments » dans un test
God class
Un possible refactoring
Notez que
● Ce code est très différent du premier– Plusieurs collaborateurs ont apparu
– Les collaborateurs sont des interfaces dans cet exemple en Java
– Les responsabilités des collaborateurs sont orthogonales
– Des injecteurs sont disponibles● Les tests utilisent ces injecteurs pour paramétrer cette
classe et faire des vérifications de collaboration
Notez aussi que
● Plusieurs chemins sont possibles● Vous avez probablement besoin d'une vision
– Un modèle cible
– Une architecture cible
– Au moins une intention cible
Modèle cible
● Une cible de type architecture hexagonale
● ...et des coeurs de la part de mes enfants pour me donner du courage ;)
Plusieurs chemins possibles
Center
Repository
ErrorLogBlankPage
Order
DisplayOrdersCommand
SqlRepository
ErrorViewOrdersView
Plusieurs chemins possibles
Center
Repository
ErrorLogBlankPage
Order
DisplayOrdersCommand
SqlRepository
ErrorViewOrdersView
1
Plusieurs chemins possibles
Center
Repository
ErrorLogBlankPage
Order
DisplayOrdersCommand
SqlRepository
ErrorViewOrdersView
1
2
Plusieurs chemins possibles
Center
Repository
ErrorLogBlankPage
Order
DisplayOrdersCommand
SqlRepository
ErrorViewOrdersView
1
2
3
Souvenez-vous
● Commencez lorsque vos tests passent● Ecoutez vos tests● Ne restez pas trop longtemps sans feedback de
la part de votre suite de tests
– En programmant par intention votre suite de tests passera du rouge au vert plusieurs fois
– En ajoutant de nouveaux tests aussi ;)
Un autre exemple
● Supprimer les commentaires– Les commentaires sont souvent désynchronisés du
code
– Remplacer les commentaires par des tests
Supprimer un commentaire
Attention
● « supprimer un commentaire » veut dire– Prendre l'opportunité d'améliorer le code
– Supprimer le bruit
– Augmenter la confiance
● « supprimer un commentaire » ne veut pas dire– Perdre la documentation
– Perdre quelque chose, quoi que ce soit
Un possible refactoring
A vous :)
Supprimer un « switch »
● Choisissez un code avec du conditionnel● « Jouez » à le supprimer● Ce type de code:
Approche par de nouveaux tests
● Choisissez une cible● Décrivez dans un test une étape qui vous
permet d'explorer cette cible● Exemple: cible === reflection
Approche par intention
● Modifiez le code comme vous voudriez qu'il soit– Faites le compiler
– Laisser votre suite de tests passer au rouge
– Revenez ensuite au vert
● Exemple:
Combinez les deux approches
● Modifiez le code comme vous voudriez qu'il soit– Faites le compiler
– Laisser votre suite de tests passer au rouge
● Identifiez une cible– Décrivez dans un test une étape vers cette cible
– Faires passer un à un les tests qui vous amène à la cible
Votre suite de tests contient plusieurs tests rouges avant de retrouver le vert complet
Auto-évaluation
Tests X / V ?
J'ai écrit plusieurs tests
Chaque nouveau test commence par ne pas passer
Chaque test a une seule intention
Chaque test a un nom qui illustre l'intention du test
Mes tests illustrent un développement incrémentale
Un autre que moi comprend l'intention de mes tests
Je sais nommer les smells que je supprime en refactoring
Mon backlog de refactoring a réduit
Je sais nommer les Design Patterns que j'ai implémenté
Je sais nommer le principe SOLID que j'ai suivi
Merci
● M'aiderez vous à améliorer ce matériel ?– Qu'avez-vous aimé ?
– Quelles améliorations feriez-vous ?