Code Retreat Lille #2 : Retour d’expérience

A l’instar d’un musicien qui doit pratiquer ses gammes entre deux concerts pour parfaire la maîtrise de son art, un développeur doit savoir “faire retraite” pour s’exercer à d’autres techniques et méthodologies que celles qu’il pratique quotidiennement.

C’est avec cette métaphore on-ne-peut-plus-compréhensible que les deux organisateurs, Jérémie Hattat et Adrian Bolboaca, nous ont présenté l’intérêt d’évènements tels que ce deuxième Code Retreat lillois, qui s’est déroulé samedi 14 janvier dans les locaux de Proxiad. Le programme de la journée s’est composé de :

  • 6 sessions de 45 minutes de programmation en binôme sur le thème du Jeu de la Vie, chacune devant nous pousser dans l’exploration par l’introduction de nouvelles contraintes,
  • Le langage d’implémentation était au choix de chaque binôme.
  • Chaque session était suivie d’une rétrospective commune, à la mode Agile, durant laquelle les participants exposaient leur approche du problème, leurs difficultés et progrès.

L’idée était bien entendu de partager les connaissances et de faire évoluer chacun, sans engager personne dans quelque compétition que ce soit.

L’intérêt de savoir implémenter le Jeu de la Vie ? Aucun.

Ce sujet était simplement l’occasion d’introduire, de pratiquer et d’expliquer les avantages du Test Driven Development (TDD) ou encore du Pair Programming ; de découvrir de nouveaux outils, tels que GIT, des trucs et astuces de développeurs ou un nouveau langage de programmation. Le but n’est pas de résoudre le problème mais bien de poser la question du cheminement ; l’important étant de progresser dans sa compréhension de ces méthodologies et de partager son expérience propre avec son binôme.

Plutôt que de vous les présenter de façon monolithique, je vais vous détailler chacune de mes sessions et l’évolution de la perception que j’en ai eu. Je ne prétends pas vous donner de réponse à toutes vos questions ni vous faire des révélations, mais simplement vous montrer la réflexion qui a été la mienne tout au long de cette journée afin de vous inciter à y participer, vous aussi.

Je préciserai simplement que c’était là mon premier Code Retreat et que je n’avais jamais pratiqué le TDD ni le Pair Programming auparavant. Je partais donc de zéro…

panoramique

1ère session : Pair-Programming … le Jeu de la Vie

Contraintes

Cette première session avait pour objectif de se familiariser avec les 4 règles principales du Jeu de la vie, mettant en scène des Cellules dans un Univers commun :

  1. Une cellule morte avec moins de trois voisins reste morte,
  2. Une cellule vivante avec moins de deux voisins meurt,
  3. Une cellule vivante avec plus de trois voisins meurt,
  4. Une cellule morte avec exactement trois voisins renaît.

4 règles basiques qui laissent cependant possibles des angles d’attaque très différents. L’idée était ainsi de les implémenter avec nos connaissances propres, sans contrainte particulière.

J’étais ici associé à un ami, d’un parcours très proche du mien. Lui non plus n’avait jamais réellement pratiqué le TDD ni le Pair Programming. Nous développions en Java, en utilisant JUnit.

Déroulement

En quelques mots échangés très rapidement en début de session, nous avons convenu d’une vision et d’une méthodologie commune :

  • Je me chargerais d’écrire le code  tandis que mon binôme se chargerait de réfléchir à l’étape suivante pour me guider dans ma réalisation. Je me chargeais donc de résoudre les problèmes techniques rencontrés sur le moment, tandis qu’il concevait la phase suivante et modélisait les règles,
  • Nous avons choisi comme approche de commencer par modéliser les Cellules et l’Univers qui les contient.

Les tests étaient en grande partie écrits avant d’implémenter le code, dans un esprit qui nous semblait proche du TDD, ce qui nous permettait de définir un contrat d’interface répondant exactement à nos besoins, sans fioriture inutile.

En 45 minutes, nous sommes arrivés à 100% de code implémenté… non fonctionnel. 2 bugs (trouvés par la suite entre deux sessions) nous ont empêché de faire le sans faute du point de vue réponse au besoin métier.

Rétrospective personnelle

Cette première session m’a permis de voir certaines choses :

  • 45 minutes pour une session, c’est court,
  • Le Pair Programming permet de confronter les idées (et donc éliminer les déchets), de définir un langage commun (permettant par exemple de mieux nommer les classes ou méthodes définies), de couvrir un périmètre fonctionnel et technique plus large car abordé de deux points de vue forcément différents. Le code s’en trouve donc plus qualitatif. En moins de 10 minutes on le comprend et, pourtant, il faut le pratiquer pour en prendre réellement conscience,
  • Sans se contraindre à des règles particulières dans l’écriture des tests, ces derniers ne couvrent pas nécessairement tout le périmètre fonctionnel et technique. Ils ont ainsi laissé échapper 2 bugs qui nous ont privé du plaisir de fournir une application en état de marche, même basique.

Rétrospective commune

Il a été très intéressant de constater les différentes approches proposées par les autres binômes. Tandis que le nôtre ne pouvait concevoir le Jeu de la Vie sans une série de bases mises en avant dans l’énoncé (comme la notion d’Univers ou de Cellules), d’autres binômes se sont orientés directement plus finement sur la notion de Cellules ou les règles régissant son cycle de vie. Adrian nous a expliqué connaître 18 approches différentes à ce problème…

Certains binômes ont passé du temps à discuter de chaque notion et de la façon de les modéliser : une Cellule peut-elle être morte ou vivante ? Ou une Cellule est-elle nécessairement vivante (une Cellule morte n’existant donc pas) ? Une Cellule est-elle une structure de données en soi ou simplement un booléen ?

Chaque vision est correcte. Aucune n’est meilleure qu’une autre. Aucun binôme n’a fourni une application totalement opérationnelle ; nous semblions être les plus avancés sur ce point.

2ème session : le TDD

Contraintes

La deuxième session avait pour objectif d’introduire les bases du TDD et de les mettre en application. Il convenait donc d’en respecter les règles de base :

  • On commence par écrire un test,
  • On ajoute les éléments qui permettent de compiler le code,
  • On vérifie que le test échoue,
  • On écrit l’implémentation qui permet de faire passer le test au vert,
  • On refactorise le code de test et/ou de production si possible.

Des éléments que j’avais déjà lus mais jamais pratiqués.

Déroulement

Pour cette session, je me suis associé à un développeur qui connaissait déjà le concept du TDD et du Pair Programming. Il m’a dès le départ proposé le principe du Ping-Pong :

  1. le premier développeur écrit le test, ajoute le code de production permettant uniquement de le compiler et vérifie qu’il ne passe pas,
  2. le second développeur implémente le code de production qui permet de le valider puis écrit à son tour un nouveau test avant de repasser le clavier au premier,
  3. Et ainsi de suite…

Chaque fois, celui qui n’a pas le clavier peut critiquer le code, signaler un oubli mais ne peut pas manipuler lui-même.

Nous étions là encore en Java et JUnit.

Rétrospective Personnelle

Il est assez déstabilisant d’avoir à côté de vous quelqu’un qui critique votre code en permanence. Non pas que ce soit frustrant ou vexant mais chacune des remarques, pertinentes, remettent en question votre façon d’aborder la problématique. Chacune d’entre elles vous oblige donc à prendre du recul en vous coupant dans votre élan mais influe directement sur la qualité du code que vous produisez. Si l’on est ouvert aux critiques, le code devient cependant rapidement plus clair et plus lisible et la perte de temps du moment est largement compensée par la suite. En vous obligeant à mieux nommer vos tests par exemple, votre binôme garantit que votre code pourra facilement être repris par un tiers.

Dans la série des petits trucs et astuces, mon binôme m’a proposé de toujours organiser mes tests avec les notions de “Given, When, Then”, en séparant chaque partie du test par un commentaire portant cette notion :

// Given
Univers univers = new Univers();
// When
univers.nextStep();
// Then
assertEquals(1, univers.getAliveCells());

La présence des commentaires délimitent clairement chaque partie du test par des informations compréhensibles de tous.

Durant cette session, nous avons de nouveau abordé la problématique du Jeu de la Vie du point de la Cellule, elle-même présente dans un Univers.

Cette session a notamment été l’occasion de découvrir l’intérêt des Code Retreat : le partage de connaissance entre les développeurs est un axe important de ce genre d’évènements. Et lorsque vous vous associez à un enseignant dans l’âme vous en ressortez nécessairement grandi. Merci Thierry (@teierii) !

Rétrospective Commune

Pas de remarque particulière.

3ème session : sans les mains !

Contraintes

La troisième session avait pour objectif de choisir nous-même des contraintes parmi :

  • Pair-Programming en Ping-Pong,
  • Pas d’instruction conditionnelle,
  • Pas de boucle,
  • Impossible de parler.

Nous avons choisi de nous tirer une balle dans le pied en choisissant les trois premières.

Déroulement

Je passerai vite sur cette session qui m’a majoritairement posé des problèmes sur la façon de structurer mon code en m’obligeant à penser différemment. Autant, se passer des boucles est relativement facile ; autant, se passer des instructions conditionnelles relève du casse-tête chinois. L’utilisation de l’opérateur ternaire a été une solution frôlant l’interdit mais finalement acceptée et utilisée ; il devient cependant très rapidement illisible. Le passage à l’héritage et à l’implémentation propre à chaque classe fille nous a semblé salvateur mais est venu trop tard dans la session pour être complètement mis en œuvre.

Rétrospective Personnelle

S’imposer des contraintes particulières sur le code est un excellent exercice pour découvrir d’autres façons d’implémenter un même comportement. Cela vous oblige clairement à avoir l’esprit ouvert aux différentes solutions et aiguise vos réflexes et connaissances de développeur en mettant en œuvre ou cherchant les patterns majeurs. Bien entendu, vous ne vous imposerez pas réellement de telles contraintes dans de véritables projets, mais acquérir ces réflexes de bonnes pratiques doit vous inciter à tendre directement vers le bon pattern, la bonne modélisation plutôt que de passer par des instructions, moins claires.

Là encore, le code en devient plus clair et plus lisible, donc plus maintenable.

Rétrospective Commune

Certains binômes ont été confrontés à des tests qu’ils ont écrits et qui, dès la première exécution, sont passés au vert sans passer par la case “échec” habituelle. Comment réagir dans ce cas ? Nos animateurs favoris répondent que si le test passe, il ne faut pas chercher à le faire échouer. Il faut bien entendu le vérifier mais un test qui passe du premier coup est généralement bon signe pour la suite.

4ème session : GIT

Contraintes

J’ai trouvé cette session un peu extraterrestre par rapport aux autres mais néanmoins particulièrement intéressante. Elle a surtout marqué un tournant dans mon approche du TDD, grâce à son objectif : se forcer à respecter des itérations extrêmement courtes (2 minutes) dans lesquelles il fallait :

  • Ecrire un test qui échoue,
  • Implémenter le code,
  • Faire passer le test,
  • Commiter le code à l’aide de GIT.

Déroulement

Je ne connaissais GIT que de nom et ne l’avais jamais manipulé. Je connaissais à peine ses grands points forts, que j’avais pu lire ici et là sur différents articles. Je me suis donc naturellement “binômé” avec un connaisseur de l’outil. Après avoir mis en place le dépôt local pour jouer le jeu des commits réguliers, nous avons pu commencer la session proprement dite.

Je me suis naturellement placé en tant que copilote et aie assisté mon binôme dans ses travaux. Impossible pour moi d’agir réellement sur le clavier, faute de connaître les commandes GIT. Parce que 2 minutes, c’est très court. Des itérations de cette durée nous montre à quel point notre connaissance des raccourcis clavier et la maîtrise de nos outils nous permet un gain de temps absolument phénoménal sur notre journée de travail.

Nous avons même “triché” en passant à des itérations de 3 minutes, qui nous ont laissé une chance d’avoir le temps de commiter (tout juste d’ailleurs).

Rétrospective Personnelle

GIT est magique. Il va falloir que je m’y intéresse sérieusement. La possibilité de switcher aussi facilement de branche dans le même répertoire m’a clairement bluffé ; de même que la simplicité de mise en œuvre de l’outil (je pense ici à l’initialisation du dépôt). Je n’ai bien entendu vu que la partie locale de l’outil, puisque nous n’avons pas partagé notre travail sur un dépôt commun, mais GIT gagne à être connu (ou, plus honnêtement, je gagnerai à connaître GIT).

Les itérations courtes ont clairement déclenché quelque chose dans mon esprit. Mon binôme n’était peut-être pas non plus étranger à l’affaire (Merci Guillaume (@guillaumewallet) pour tes explications avisées ! voir son article sur l’évènement). Impossible avec de telles itérations d’aborder les problématiques du Jeu de la Vie d’un point de vue entité métier, et donc classe. Il était absolument nécessaire de penser beaucoup plus atomique, de penser à la règle unitaire. C’est un exercice que je n’ai pas réussi,  la session étant trop courte pour que je puisse avoir le déclic et appliquer en même temps le concept. Mais les sessions suivantes, dont les contraintes s’enchaînent astucieusement pour nous mettre sur le bon chemin de la compréhension, me donneront l’occasion de me rattraper.

Rétrospective Commune

Lors de la rétrospective commune, Adrian nous a appris qu’il se forçait régulièrement à travailler par itérations d’environ 5 minutes, y compris dans son travail “réel”. Comme nous l’avions constaté, cela l’oblige à réduire son périmètre de réflexion et à se concentrer sur des éléments atomiques. Ses tests en sont plus précis, plus clair. Il committe ainsi toutes les 5 minutes. Etant donné que GIT oblige à saisir un message (tous les contrôles de sources devraient le faire par défaut), il signale qu’il est plus facile pour tous les développeurs de retrouver une modification particulière et de comprendre la raison d’un changement, plutôt que d’essayer de trouver la modification dans un lot beaucoup plus important.

Inversement, je lui demande ce qu’il en est lorsqu’il committe 100 fois par jour dans une équipe de 10 personnes. Le nombre de commits est alors conséquent et parcourir les X pages d’historiques n’est pas des plus engageant. Adrian convient que c’est un compromis à trouver,  mais m’apprend que GIT permet également de committer sur le dépôt central un ensemble de commits de son dépôt local, ce qui permet de grouper les modifications en une seule et sous un même message. Difficile de ne pas alors penser que l’on se retrouve dans un cas de commit d’un lot important de plusieurs fonctionnalités, les unes pouvant de nouveau se noyer dans les autres… Je me demande ce que cela vaut réellement en entreprise sur un projet réel…

dashboard1

5ème session : TDD “as if you meant it”

Contraintes

Cette nouvelle session avait pour objectif de continuer sur la lancée de l’écriture de tests orientés règles atomiques avec l’utilisation d’une méthodologie nommée “TDD as if you meant it” :

  1. Ecrire un seul test qui échoue,
  2. Faire passer le test en implémentant le nécessaire dans le test même,
  3. Déplacer l’implémentation de la règle dans :
    • Une nouvelle méthode,
    • Ou dans une méthode existante,
  4. Créer seulement de nouvelles méthodes dans la classe du test,
  5. Créer une nouvelle classe de production  seulement pour y placer une méthode existante provenant d’une classe de test,
  6. Faire le refactoring nécessaire,
  7. Revenir en étape (1).

Déroulement

Pour cette session, je me suis “re-binômé” avec mon ami de la première session, l’objectif étant de faire le point sur nos connaissances acquises séparément dans les sessions précédentes et d’en constater les impacts sur notre méthodologie.

D’un commun accord, nous sommes repartis sur le principe du Pair-Programming en Ping-Pong afin que nous ayons tous les deux le temps de mettre en œuvre la procédure.

Rétrospective Personnelle

J’ai toujours aimé suivre des procédures claires et nettes, quitte à en établir moi-même et à les faire appliquer à mon équipe si le contexte le permet. Cette procédure n’échappe pas à la règle. Elle est claire, précise et n’est pas soumise à l’interprétation. Le simple fait de la suivre garantit un minimum de succès. Le premier test prend nécessairement un peu de temps à écrire car il faut s’approprier la suite de règles mais celle-ci devient rapidement évidente car tout-à-fait logique.

Le déclic que j’ai eu lors de la session précédente s’est parfaitement adapté à cette méthode qui incite à tester une seule règle métier. Je me suis alors mis à voir les applications métier comme un repository de règles métier et non plus comme un package d’objets métier. Le concept d’orienté-objet, si chèrement prôné dans les différents cursus de formation, n’est plus une fin en soi mais un support permettant l’implémentation, l’organisation et la présentation de ces règles.

Seules comptent les règles en définitive.

Qu’importe réellement la notion de Client ou d’Adresse ? Ce qui compte, c’est avant tout ce qui fait la valeur ajoutée de l’application : son métier, c’est-à-dire ses règles. Bien entendu, la notion de structure est nécessaire pour véhiculer les données mais les voir comme autre chose qu’un moyen de transport revient à leur donner trop d’importance.

Cette prise de conscience m’a alors révélé tout l’intérêt de l’approche des BRMS, type Drools, que j’avais eu à manipuler de nombreux mois auparavant et dont j’étais resté totalement hermétique malgré tous mes efforts et ma prise de recul. Ces outils sont typiquement des banques de règles qui utilisent des structures pour véhiculer des données et non pas l’inverse. La logique et donc son approche sont différentes, voire déstabilisantes pour certains.

En suivant, cette méthodologie “TDD as if you meant it” au pied de la lettre, nous avons réussi à réécrire totalement différemment toutes les règles principales gérant le cycle de vie d’une Cellule dans le cadre du Jeu de la Vie… en une seule ligne !

Avec TDD "as if you meant it"

Avec TDD "as if you meant it"

En une seule ligne écrite logiquement et clairement, nous avons simulé le même comportement qu’une fonction de plus de 15 lignes obscures implémentées au cours de notre première session.

Sans TDD "as if you meant it"

Sans TDD "as if you meant it"

Le pouvoir de factorisation de cette méthode est très impressionnant ; d’autant plus que peu d’efforts sont requis pour le produire.

La seule difficulté que nous avons rencontrée a été de définir le prochain test que nous devions écrire. Je (nous ?) manque clairement d’expérience dans ce domaine pour arriver à circoncire de façon claire et nette la prochaine règle atomique à tester. Il faut pour cela pratiquer pour se déshabituer des règles de codage plus conventionnelles.

Rétrospective Commune

Pas de remarque particulière.

6ème session : a new beginning

Contraintes

As we want ! Le but ici est de faire le point ou revenir sur les différentes méthodologies de la journée qui nous ont marquées, interrogées, laissées pantois.

Déroulement

On ne change pas une équipe qui gagne. Notre binôme fétiche est reparti pour un tour afin de tenter l’implémentation complète de l’application en pur TDD, histoire de boucler la boucle…

Rétrospective Personnelle

… bon, ok. On n’a pas réussi. La fatigue aidant (la journée a duré près de 9 heures pendant lesquelles l’attention et l’apprentissage intensifs ont eu raison de nous), nous n’avons pas réussi à être suffisamment rapides pour tout implémenter. Mais la voie était la bonne…

Rétrospective Générale de la journée

Premier Code Retreat.

Je n’ai pas été déçu par la formule…

Je pensais trouver un animateur présentant les grandes lignes à l’aide d’un PowerPoint et nous laissant trouver notre chemin seuls sur notre ordinateur (un souvenir de certains cours peut-être). J’ai trouvé deux animateurs impliqués, riches en conseils, donnant les pistes pour nous permettre de cheminer nous-même à travers nos questions sans jamais donner directement les réponses. J’ai trouvé des binômes soucieux de partager, clairement habitués à l’exercice, n’hésitant pas à consacrer une partie de la session aux explications, toujours avec humilité.

La formule est tout simplement excellente. Si les participants sont toujours de cette qualité, ce genre d’évènements ne peut que contribuer à vous faire progresser et vous enrichir techniquement et humainement.

Première mise en pratique du TDD.

Comme je le partageais lors de notre rétrospective finale, j’ai pris une grande claque.

Je ne connaissais qu’une seule façon d’aborder l’implémentation, celle que l’on m’a apprise, que j’ai perfectionnée en pratiquant : on modélise les objets métiers, on refactorise pour respecter les patterns, on implémente le code de production et on vérifie que tout fonctionne en implémentant les tests.

Le TDD est clairement une approche totalement différente dont on ne peut comprendre les avantages qu’en le mettant réellement en pratique.

Il me reste cependant de nombreuses questions :

  • Nous n’avons vu que comment ajouter de nouveaux tests et du nouveau code de production. Comment doit-on procéder lorsqu’il s’agit de retirer du code ou de refondre une application existante écrite en TDD ? Y a-t-il également une méthodologie particulière à suivre ?
  • Le TDD tel que nous l’avons pratiqué part des règles métier pour ajouter au fur et à mesure les objets métier qui émergent. L’avantage est évidemment de n’avoir que ce qui est nécessaire mais, si l’on ne peut pas prévoir précisément ce dont on a besoin, comment estimer la durée d’implémentation de l’application ? Et, s’il n’est pas possible de faire d’estimation, comment faire pour gérer une équipe, estimer le budget nécessaire, les dates de livraison, … ? La réponse est-elle uniquement : le TDD ne se pratique qu’en mode Agile avec un client qui accepte ce principe de fonctionnement ? Il me manque des éléments pour répondre que seule l’expérience (la mienne ou celle des autres) peut apporter. Un avis sur la question ?
  • Quid du fonctionnement global de GIT, des repositories communs ? Il est assez facile de répondre à cela : il suffit de télécharger l’outil et de pratiquer un peu chez soi :-)

Pour conclure, une très belle journée que ce Code Retreat. Un joli moment de partage et de découverte. Un grand merci aux organisateurs, Jérémie et Adrian, en souhaitant que ces évènements se multiplient et que la communauté lilloise se développe et s’anime d’autant plus !

Voici des photos de l’évènement :
m4s0n501

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>