La première itération et l'angoisse de la page blanche

Les méthodes agiles, à travers leurs approches itératives et incrémentales, ont pour caractéristique commune de maintenir en permanence (ou presque) un logiciel dans un état "prêt à livrer". Le travail suit donc un rythme très régulier et sans cassure : pas grosse phase de "conception" ou d'"intégration" pour ne citer que les passages les plus délicats de projets menés en mode moins agile.
Cet état "prêt à livrer" requiert toutefois une condition importante : qu'il y ait quelque chose à livrer ! Et c'est typiquement le problème de tout début de vie d'un produit quand s'opère le passage d'un néant à un premier livrable, aussi minimal soit-il.

Pour démarrer un projet, on entendra alors parler de "phase de lancement", ou bien de "sprint 0", ou encore de "phase exploratoire".
Quelle que soit la dénomination, il s'agit de mettre l'équipe (pris au sens le plus large possible) sur des rails pour commencer à travailler en mode incrémental, ce qui implique d'avoir une vision partagée à travers un backlog de produit et un socle technique.

Mais comment procéder lorsque l'on part d'une base de code vierge ? La tentation est grande de définir une architecture a priori au lieu de laisser celle-ci véritablement émerger des besoins. En effet, implémenter la moindre histoire utilisateur à partir de rien nécessite généralement bien plus de code que lorsqu'une architecture est déjà en place.

Et pourtant, Kent Beck, dans Extreme Programming Explained, conseille explicitement de choisir des histoires utilisateurs pour diriger, dès le départ, la construction du système complet :

The first iteration puts the architecture in place. Pick stories for the first iteration that will force you to create "the whole system," even if it is in skeletal form.
Picking stories for subsequent iterations is entirely at the discretion of the customer. The question to ask is, "What is the most valuable thing for us to be working on in this iteration?"

L'utilisation des histoires dès le début présente plusieurs intérêts :

  • les choix techniques sont faits pour répondre à un besoin réel et immédiat et non pas en prévision d'un hypothétique futur.
  • le travail de développement est fluidifié. Il n'y a pas de cassure entre une phase où on fait des choix fondamentaux et une phase où on commence à dérouler l'implémentation d'histoires utilisateur.

Pour pallier à la nécessité d'écrire du code à partir de zéro sans crouler sous les besoins techniques sous-jacents à la moindre histoire, on peut, par exemple, procéder de la façon suivante :

  • le client (ou le directeur de produit selon le nom en vigueur dans la méthode utilisée) liste 4 ou 5 histoires qui seront centrales dans la définition du produit
  • l'équipe découpe ces histoires en éléments de plus fine granularité correspondant chacun à une valeur ajoutée si le reste du système existait déjà. Par exemple, une histoire où "l'utilisateur visualise des résultats d'un calcul utilisant des valeurs présentes dans une base de données" peut être découpée en :
    • le rajout d'un calcul sans se soucier de la présence d'une base de données ou d'un dispositif d'affichage
    • le rajout d'une base de données en supposant que des calculs existent déjà à partir d'une autre source de données
    • le rajout d'une visualisation en supposant que des calculs existent déjà et utilisent un autre dispositif d'affichage
  • l'équipe estime ces élements (planning poker, etc.) et se crée ainsi une base de référence pour ses estimations futures
  • l'équipe démarre l'implémentation et le client commence à étoffer son backlog de produit avec des histoires qui viennent se rajouter sur le système tel qu'il a commencé à être défini