Comment se débarrasser des dépendances entre histoires utilisateurs, grâce à la Théorie des Contraintes

Bruno Borghi
Les Cahiers Agiles
Published in
7 min readJun 20, 2019

En agile, on pilote par la valeur. On décrit le produit à réaliser comme une collection d’histoires utilisateur (en franglais : user stories). Pour chaque histoire, on évalue une valeur business — la valeur du résultat pour l’utilisateur — et un effort de réalisation. On classe les histoires par priorité dans un backlog produit et il ne reste plus qu’à réaliser les histoires dans l’ordre du backlog pour être certain de maximiser à tout moment la valeur délivrée.

C’est la promesse de l’agilité.

Alors, on s’y met, on construit un backlog produit.

Et là, paf, presque aussitôt, on tombe sur des problèmes de dépendances entre histoires.

C’est embêtant. Parce qu’on sait bien que le graal du projet agile, c’est d’avoir une collection d’histoires in-dé-pen-dantes. L’eXtreme Programming a consacré l’acronyme “I-N-V-E-S-T”, avec I pour In-dé-pen-dante.

Malheureusement, l’acronyme INVEST ne nous est d’aucun secours pour atteindre notre graal et résoudre les dépendances en pratique.

En gestion de projet classique, les dépendances entre tâches sont nos amies, la base du travail de planification. En agile, les dépendances entre histoires utilisateur sont nos ennemies jurées.

C’est pourquoi je vous propose ci-dessous une méthode simple d’analyse et de résolution des dépendances entre histoires utilisateur. Cette méthode consiste à appliquer le processus de pensée dit “diagramme de résolution de conflit” décrit par Eliyahu M. Goldratt dans sa Théorie des Contraintes (TOC), théorie qui a révolutionné, entre autres, l’organisation des processus industriels.

Première étape

Supposons que nous soyons dans la situation où l’équipe de réalisation considère que l’Histoire A dépend de l’Histoire X.

Reformulons la situation dans le vocabulaire de la Théorie des Contraintes. Réaliser l’Histoire X est considéré comme un pré-requis à réaliser l’Histoire A.

La première étape de la méthode de résolution consiste à expliciter les raisons de cette dépendance : “Réaliser l’Histoire X est un pré-requis à la réalisation de l’Histoire A parce que…”.

On fait alors la liste des raisons. C’est un travail qui mérite de se faire à plusieurs. On écarte ensuite les mauvaises raisons. Enfin, pour chaque bonne raison, on cherche à expliciter les hypothèses cachées qui justifient le pré-requis — c’est la partie difficile du travail. On examine soigneusement chaque hypothèse pour déterminer si l’hypothèse est valide ou erronée.

Exemple typique

Le produit à réaliser est une application de réservation de salle de réunion. L’Histoire 1 est : “Réserver une salle à une date que je choisis”. L’Histoire 2 est : “Annuler la réservation d’une salle”. L’équipe considère que l’Histoire 2 dépend de l’Histoire 1. Réaliser “Réserver une salle” est un pré-requis pour la réalisation de “Annuler une réservation de salle”. On ne peut pas coder l’annulation avant d’avoir codé la réservation, n’est-ce pas ?

Quelle est la raison qui justifie ce pré-requis ? Réponse typique : on ne peut pas annuler une réservation de salle si la salle n’a pas été auparavant réservée.

Je vous invite à prendre quelques instants, avant de poursuivre la lecture, pour répondre par vous-même à la question qui vient ensuite : quelle est l’hypothèse cachée ?

À la réponse typique correspond une hypothèse cachée typique : réserver la salle au moyen de l’application serait l’unique façon possible pour qu’une salle soit déclarée comme réservée dans le planning de réservation.

Or, il est facile de voir que cette hypothèse est erronée. Pour qu’une réservation puisse être annulée, il suffit que la réservation soit dans le planning ; peu importe la façon dont elle y a été inscrite. Dans la plupart des projets, un script SQL qui demande 10 minutes de développement fait l’affaire.

Conclusion : l’Histoire 1 et l’Histoire 2 sont en fait indépendantes et peuvent être réalisées dans l’ordre qui nous arrange.

Deuxième étape

Il se peut qu’à la fin de la première étape, on ait encore des bonnes raisons et des hypothèses valides pour penser qu’il existe une dépendance entre les histoires. La question à se poser alors est la suivante : est-ce que ce ne serait pas aussi simple de considérer ces deux histoires comme une seule histoire ?

On applique à nouveau le processus de pensée à l’assertion “L’Histoire A et l’Histoire X sont nécessairement deux histoires distinctes parce que…”. On établit la liste des bonnes raisons, puis on cherche les hypothèses cachées derrière ces bonnes raisons.

La bonne raison typique dans une telle situation est que l’effort total pour réaliser à la fois l’Histoire A et l’Histoire X ne tient pas dans une seule itération. À ce moment-là, il peut même arriver que certains développeurs se mettent à grommeler qu’ils l’avaient bien dit, une itération de deux semaines, c’est trop court. Confronté à une tentative de mutinerie, le Scrum Master ne peut s’en sortir qu’en exhibant les hypothèses cachées.

L’hypothèse cachée typique est ici : il n’y aurait qu’une et une seule façon de découper le problème, et ce serait de le découper précisément en cette Histoire A et cette Histoire X.

Cette hypothèse cachée est souvent erronée. La voie de résolution est de décomposer en tranches fonctionnelles selon un autre axe.

Les critères d’acceptation donnent souvent des pistes intéressantes pour trouver des façons de découper les histoires.

Troisième étape

À la fin de la deuxième étape, il se peut qu’il y ait encore de bonnes raisons avec des hypothèses valides. Mais c’est rare.

Dans ce cas, la troisième étape consiste à challenger la recherche d’indépendance en appliquant toujours le même processus de pensée, cette fois à l’assertion : “L’équipe ne doit pas réaliser l’Histoire X avant l’Histoire A parce que…”.

Habituellement, à ce stade, il n’y a plus que des mauvaises raisons, souvent motivées par une approche exagérément dogmatique de la mise en oeuvre des frameworks agiles. On respectera alors la dépendance et on réalisera l’Histoire X avant l’Histoire A.

Interdépendance, optimums locaux, optimum global

La Théorie des Contraintes démontre qu’en privilégiant les optimums locaux, on dégrade l’optimum global. Par exemple, optimiser indépendamment chaque étape d’un processus mène le plus souvent à une dégradation de la performance du processus global, car les difficultés liées au passage d’une étape à l’autre sont négligées.

L’examen des dépendances entre histoires peut parfois conduire à une situation d’optimisation locale au détriment de l’optimum global.

Prenons un exemple. Dans le cadre de la réalisation d’une application de commerce, l’Histoire 1 est “En tant que client, je veux pouvoir payer avec ma carte Visa”. L’Histoire 2 est “En tant que client, je veux pouvoir payer avec ma carte Mastercard”. L’équipe considère que les deux histoires ne sont pas indépendantes. Pire, ces histoires sont interdépendantes.

La raison invoquée typique est : si l’histoire du paiement par Carte Visa a été réalisée, alors l’histoire du paiement par carte Mastercard sera ensuite beaucoup plus facile à réaliser que si l’histoire du paiement par carte Visa n’avait pas été réalisé auparavant. Et réciproquement. Il y a interdépendance dans la taille de l’effort. Une telle situation est souvent considérée comme une dépendance technique.

En fait, il n’en est rien. Chacun sait en son for intérieur qu’on peut commencer par n’importe laquelle des deux histoires sans changer la face du projet.

Faisons la liste des hypothèse cachées :

  • Hypothèse cachée 1 : il est nécessaire d’estimer l’effort de réalisation de ces deux histoires indépendamment l’une de l’autre ;
  • Hypothèse cachée 2 : l’effort estimé pour chacune de ces histoires doit être exact, c’est à dire que l’effort réalisé pour chacune de ces histoires doit être égal à l’effort estimé initialement ;
  • Hypothèse cachée 3 : l’effort estimé pour une histoire est nécessairement un nombre de la suite de Fibonacci.

En faisant ces hypothèses, on privilégie les optimums locaux — l’estimation de chaque histoire prise individuellement — au détriment d’un optimum global — l’estimation de l’ensemble des histoires de l’itération.

Pour privilégier l’optimum global, il faut se libérer de ces trois hypothèses. Le processus consiste alors à :

  • 1/ estimer l’effort de réalisation du paiement Visa en supposant qu’on commence par le paiement Visa, par exemple 21 points ;
  • 2/ estimer l’effort de réalisation du paiement Mastercard en supposant qu’on a déjà fait le paiement Visa, par exemple 8 points ;
  • 3/ sommer les deux valeurs pour obtenir l’effort total pour les deux histoires, en l’occurrence 29 points ;
  • 4/ répartir les points à égalité entre les deux histoires, soit 15 points chacune.

Les deux histoires sont devenues indépendantes, tout en respectant une estimation globale raisonnable de l’effort à fournir pour les réaliser.

 by the author.

--

--