Blog Arolla

TDD, une affaire de design

Le sujet de la semaine, c'est une longue conversation sur Twitter entre Sandro Mancuso (@sandromancuso), Ron Jeffries (@ronjeffries), et Joe Rainsberger (@jbrains) et quelques autres sur les relations entre TDD et le Design. On rappelle que TDD est habituellement présenté comme une technique de design.

Sandro a commencé par affirmer que TDD avait besoin de compétences en design au préalable.

I believe software design should be taught before TDD. TDD can’t lead to good design if we don’t know what good design looks like. - @sandromancuso

Joe et Ron ont challengé cette affirmation, mais davantage sur la forme que sur le fond.

Faut-il apprendre les techniques de design pour faire du TDD ?

Au fil de cette conversation il apparaît clairement un contraste entre la vision de TDD des pionniers à la fin des années 90, et la vision des nouveaux praticiens TDD de la fin des années 2000.

Pour les pionniers, l'industrie logicielle à la fin des années 90 avait un focus marqué sur le design. Les techniques de design orientées-objet étaient nombreuses, certaines compliquées ou parfois exotiques. On se passionnait pour les patterns, bien au-delà des 23 design patterns. On débattait de cohésion et de couplage. Oncle Bob publiait sur les principes SOLID. On parlait de la loi de Demeter, de rôles et de responsabilités, de techniques d'analyse comme les CRC Cards.

On faisait aussi du design avant de coder (Big Design Upfront, BDUF). Et quand on parlait de design, UML n'était pas loin. Pire encore, le design était considéré noble tandis que coder était parfois considéré sale, ou au mieux automatisable, avec des démarches telles que MDA.

En tout cas pour être crédible à cette période il fallait s'y connaître en design. C'était donc le cas de la plupart des développeurs qui font autorité aujourd'hui en XP, Agile et TDD.

Le manifeste agile est arrivé un peu en réaction aux excès de cette période, avec TDD au premier rang. Au-delà du rejet des aberrations en gestion des projets de développement logiciel, on rejette aussi les excès du design pour le design.

tdd-red-refactor-green

Arrêtez de spéculer sur les besoins futurs, privilégiez la simplicité et l'humilité. Commencez toujours par des tests, par petits pas. Refactorez, tout le temps !

Histoire d'un malentendu

I have the feeling that our industry is going from BDUF to “no design at all”, only relying on TDD with no foundation. - @sandromancuso in reply to @jbrains

Depuis si on écoute les partisans de TDD, dont je fais partie, on peut légitimement avoir l'impression qu'avec TDD le design émerge spontanément, "mécaniquement", et même pourquoi pas "forcément" de l'application rigoureuse du cycle Test-Code-Refactor de TDD. Ce n'est pas malheureusement pas du tout le cas.

L'application rigoureuse de TDD attire en effet l'attention sur les problèmes de design, par exemple parce que le code est difficile à tester. TDD suggère d'améliorer par du refactoring permanent. TDD ne dit pas comment améliorer concrètement, parmi toute la variété des changements de code possibles.

On couple toujours TDD avec les 4 règles de Simple Design (4RoSD), présentées sur le site web de Joe Rainsberger :

I define simple design this way. A design is simple to the extent that it:

  1. Passes its tests
  2. Minimizes duplication
  3. Maximizes clarity
  4. Has fewer elements

Néanmoins même en suivant TDD à la lettre, avec ces 4 règles et avec la meilleure volonté du monde, on échappe certes au pire car au moins le code est testable ce qui nous donne une option pour le refaire, mais rien n'empêche le design de mal tourner.

Par exemple on peut réduire la duplication avec des fonctions statiques dans des classes Helper, ou en factorisant des bouts de calcul dans des variables locales, par exemple des booléens. On peut aussi ajouter encore des paramètres de plus à une méthode qui en a déjà beaucoup, histoire de la réutiliser dans un nouveau cas. Tout cela semble vérifier les règles, mais c'est du design particulièrement médiocre. Pour beaucoup, dans ces conditions, TDD sera une déception. Les tests sont verts, mais le design est très décevant.

TDD ne suffit pas tout seul pour mener à du bon design. Mais TDD mène vers le bon design. Il est où le truc ?

Joe Rainsberger revendique que TDD se suffit même sans compétences de design a priori. Dans son expérience propre et sa vision, le guidage de TDD et des 4 règles de Simple Design ont suffi à lui montrer ses faiblesses et l'ont guidé vers les bonnes personnes et les bons articles sur les techniques de design à connaître. Il a donc étudié toute cette littérature progressivement, en même temps que sa progression dans la démarche TDD.

Quand apprendre les compétences en design ?

On voit à ce point qu'on joue sur les mots, leur compréhension et leur contexte. Mais il n'y a pas vraiment de contradiction. TDD n'est pas auto-suffisant. Les techniques de design sont nécessaires et doivent être apprises et pratiquées à un moment ou à un autre. TDD est un framework qui aide à signaler quand le design est à améliorer.

Vous pouvez décider d'apprendre les techniques de design au préalable. Après tout c'est mon parcours et celui de bon nombre de praticiens qui ont débuté avant 2000, et qui ont appris TDD plus tard. Dans ce cas le risque est de s'attacher aux techniques de design et à leur contexte idéologique parfois dépassé (phase de design préalable et trop longue, UML, abus de patterns, excès de confiance dans ses compétences en design...). Il faudra désapprendre des choses lors du passage à TDD.

L'alternative est de commencer directement par TDD, et d'écouter attentivement les frustrations quotidiennes. Chaque douleur, chaque friction est un signal qui indique une compétence en design qui vous manque. À la façon de Joe Rainsberger, vous pouvez alors fouiller sur le web, ou mieux encore demander conseil à d'autres passionnés lors des multiples Meetups (*) sur le sujet. Cette approche est certainement plus attractive aujourd'hui. Apprendre dirigé par le besoin, dans le bon contexte, et seulement ce qui est pertinent.

C'est aussi notre approche chez Arolla. TDD d'abord, mais en entremêlant assez tôt les techniques de base de design. L'apprentissage de BDD, des techniques de remédiation de code legacy ou de DDD s'appuient ensuite sur cette base TDD fondamentale.

Si vous faites du TDD ou que vous décidez aujourd'hui de vous y mettre sincèrement, vos compétences en design, orienté object (OO) mais aussi désormais en programmation fonctionnelle (FP) vous seront précieuses pour tirer le meilleur de TDD.

Exemples de meetups parisiens où on peut coder :

Paris Software Craftsmanship

Extreme Programming Paris

Duchess Frances

Jam de Code

Dojo Developpement Paris

Ladies Who Code Paris

Site Web | Plus de publications

Directeur Technique d'Arolla

4 comments for “TDD, une affaire de design

  1. 23 avril 2015 at 22 h 36 min

    Par exemple on peut réduire la duplication avec des fonctions statiques dans des classes Helper, ou en factorisant des bouts de calcul dans des variables locales, par exemple des booléens. On peut aussi ajouter encore des paramètres de plus à une méthode qui en a déjà beaucoup, histoire de la réutiliser dans un nouveau cas. Tout cela semble vérifier les règles, mais c’est du design particulièrement médiocre. Pour beaucoup, dans ces conditions, TDD sera une déception. Les tests sont verts, mais le design est très décevant.

    Oui, mais seulement pour un certain temps. Si on persiste à réduire de la duplication uniquement à l’aide des fonctions statiques, on arrivera au moment ou la duplication des noms de fonction se fera évidente. Comment réduire cette duplication?–bien sûr en mettant ces fonctions en modules découplées et séparées. Dans ces modules, certains paramètres deviennent propriétés/champs/membres. Voilà–c’est comme ça que la cohésion s’améliore.

    Il est vrai que des programmeurs aussi déterminés puissent toujours produire des conceptions bizarres, mais je ne m’y intéresse pas beaucoup. Je m’intéresse pour la plupart aux personnes qui auront toujours la tendance à se demander : “les règles de conception simple indiquent à faire X, mais en ce faisant, elles me rendent là où cette règle-ci semble violée–qu’est que ça signifie?!” Ces programmeurs vont développer un bon “design sense”, même si au départ (comme c’était le cas pour moi) ils sont entièrement dans la merde avec les principes de conception.

  2. Saad Bourziza
    1 juin 2015 at 15 h 49 min

    Même si le TDD ne mène pas directement à un bon design, il permet d’adoucir les conséquence d’un mauvais design.

    Avec le TDD, une fois qu’on découvre que notre design n’est pas idéal, on peut faire autant de changements qu’on veut pour l’améliorer, sans craindre de casser une fonctionnalité et de créer un bug. Le TDD nous donne l’assurance que notre programme fonctionne toujours correctement, et la liberté d’améliorer notre code jusqu’à être satisfait.