Pièges de l'Agile n°2: L'Agile endetté
Tranches de vie
Voici un extrait d'une conversation entendue pendant la rétrospective de fin d'itération d'un projet Agile A, entre les Développeurs et le Product Owner :
P.O: Avec seulement deux stories sur les sept planifiées en début de sprint, je peux vous dire qu'on n'avance pas à un bon rythme. Dév. 1: C'est clair. P.O: Ce qui pose le problème de ce que l'on va être capable de montrer à la démo du COMEX. Ça a une certaine importance, parce que je comptais sur cette démo pour faire avancer les choses du côté du service utilisateur. Dév. 1: Clairement durant ce sprint on a été énormément ralenti.. P.O: Par quoi ? Les stories que je produis ne sont a priori pas plus compliquées que d'habitude. Dév. 2: OK, moi je pense savoir ce qui nous ralentit.. P.O: On t'écoute. Dév. 2: Ce qui nous ralentit, c'est qu'on a de la dette technique à ne plus savoir qu'en faire: il y a des modules entiers sans tests unitaires, d'où tous ces bugs qu'on a dû corriger pendant le sprint; il y a beaucoup de code redondant, et du code mort aussi, certaines parties du code sont incompréhensibles pour moi, et elles ne respectent pas les conventions de noms habituels.. Dév. 3: Tu veux parler du code de Jean-Michel? Dév. 2: Pas seulement, en fait. Dév. 1: Bref, en ce moment, c'est un peu compliqué de faire plus vite.
Voici un extrait d'une conversation entendue pendant la rétrospective de fin d'itération d'un projet Agile B, entre les Développeurs et le Product Owner:
P.O: J'ai drôlement apprécié que vous ayez réussi à mettre en place le système de localisation pendant ce sprint! Ça va en jeter pour la démo du côté du service utilisateur! Dév. 1: Ah oui! Tant mieux. P.O: Alors merci pour ça! Dév. 1: Bah de rien. Dév. 2: Oui mais: ce système de localisation il faudra le revoir.. P.O: Ah bon, pourquoi ? Dév. 2: Parce qu'on a violé certaines de nos règles de design pour l'implémenter. C'est un hack. P.O: Qu'est-ce que tu entends par "un hack" ? Dév. 1: Une solution temporaire en quelque sorte. Bref c'est de la dette technique. Dév. 3: Tiens d'ailleurs, je mets la tâche de refactoring pour le sprint suivant. Dév. 2: Post-it violet! La dette technique, c'est en violet. Dév. 3: Ah oui, merci.
Dette technique ?
La différence marquante entre ces deux conversations, c'est l'usage qui est fait de l'expression "dette technique". Dans le projet A, l'équipe rencontre des problèmes de qualité interne qui l'empêchent de livrer autant de fonctionnalités qu'elle le voudrait, et c'est ce qu'elle désigne par "la dette technique". Dans le projet B, l'équipe rencontre peut être des problèmes de qualité, mais en tout cas, ce n'est pas ce qu'elle désigne par "dette technique". Ce qu'elle designe, précisément, par ce terme, c'est la mise en place d'une solution temporaire, n'obéissant pas aux standards habituels de l'équipe, mais qui permet de gagner du temps à court terme.
Dans le premier cas, le terme désigne une manière de qualifier le code, de parler de sa qualité générale, qui pour le coup paraît relativement préoccuppante, bien qu'aucun remède ne semble clairement identifié. Dans le deuxième cas, il désigne un expédient temporaire, un écart ponctuel aux standards de l'équipe, pour lequel une solution de recouvrement est non seulement identifiée, mais en plus planifiée dans le temps. Bien sûr, on pourrait dire que l'équipe A a pu se "surendetter" à coups d'expédients successifs. D'ailleurs, Ward Cunningham, qui est l'auteur de cette analogie, pointait déjà — il y a plus de 20 ans — le risque de dérive vers un endettement technique généralisé:
Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite... The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation, object-oriented or otherwise.
En effet, lorsque l'équipe "emprunte techniquement", c'est à sa propre vélocité future, ainsi qu'au client indirectement: sans un prompt remboursement, celui-ci sera à terme gratifié d'une solution temporaire qui a rendu service sur le coup, mais qui a aussi fait long feu. Qui coûte, maintenant, bien cher. Et on sait qu'en logiciel, paradoxalement, le temporaire dure.
De la métaphore au modèle
Continuer d'appeler "dette technique" ce qui relève en fait d'un problème général de qualité dans le design ou le code d'une équipe, fait perdre toute son utilité à cette métaphore. Considérez l'endettement financier d'une entreprise: l'entreprise s'endette afin d'investir, et elle investit afin de s'enrichir. Aucun chef d'entreprise ne déclarerait : "Nous nous endettons, nous ne contrôlons pas vraiment le phénomène, et n'avons pas vraiment d'idée de ce qu'il faut faire pour y remédier, mais en attendant, c'est ce que nous faisons".
En revanche, dans le monde de l'IT, tout le monde ou presque utilise aujourd'hui la notion de dette technique précisément dans ce sens, c'est à dire, finalement, pour exprimer l'idée d'une fuite en avant. Comme il est difficile de constater une fuite — même une fuite en avant — sans tenter de montrer qu'on ne reste pas à rien faire devant le problème, on a également identifié des moyens de mesurer la dette technique — un exploit dans l'art de faire dire aux chiffres n'importe quoi — passant ainsi subtilement de la métaphore, au modèle d'analyse d'impact. C'est dire si le problème du surendettement technique incontrôlé s'est répandu. Or une équipe engluée dans la dette technique au point d'avoir besoin d'outils pour la mesurer, c'est un peu comme une équipe qui déclarerait: "Nous accumulons des problèmes de qualité interne, nous ne contrôlons pas vraiment cette dégradation, et nous n'avons pas vraiment de contre-mesure, mais en attendant, nous pouvons la mesurer, et c'est ce que nous faisons".
Cette métaphore est-elle utile à une équipe au prise avec des problèmes de qualité? C'est douteux. Lorsque le Product Owner — ou le Manager, ou le Technical Leader, ou qui vous voulez — n'est pas en mesure de traiter efficacement l'alerte sur les agios exorbitants que l'équipe est déjà en train de subir, que peut signifier s'endetter techniquement ? Utiliserait-on encore la notion de dette dans un système financier où la banque ne viendrait jamais réclamer le paiement des termes, principal et intérêt ?
Chaque équipe utilise évidemment les métaphores comme elle l'entend pour désigner telle ou telle partie de sa réalité. Mais lorsqu'une équipe se se réfère à un pattern, comme par exemple Singleton ou Observateur, c'est en général dans l'idée d'utiliser ce pattern tel qu'il a été documenté, afin de remédier à un problème similaire à ceux que le pattern résoud habituellement. Or avec l'équipe citée en premier exemple, il semble que l'emploi du terme ne sert aucune démarche particulière, si ce n'est jeter un voile pudique sur une réalité dure à admettre (que certains appellent, loin des slides officiels, le "code écrit à la rache"). Force est de constater qu'on est passé du pattern à l'anti-pattern.
Comment s'y repérer ?
Pour autant faut-il jeter le pattern aux orties? Loin s'en faut. Comme le montre l'exemple de l'équipe B, la notion d'emprunt à court terme est particulièrement utile — parce qu'elle décrit une situation nécessaire, inévitable dans toute équipe Agile, à savoir le conflit entre les besoins à court terme du projet, de l'équipe, du client, et les besoins à moyen ou long termes de ces mêmes parties. Si elle ne cherchait pas à être Agile, l'équipe excellente ne contracterait jamais de dette technique. Et c'est parce qu'elle recherche l'excellence autant que l'agilité, que l'équipe Agile utilise ce pattern. Si on comparait le travail d'une équipe de développement à une partie d'échec, ou pourrait exprimer cette différence comme suit:
- La dette technique "tactique", c'est comme un sacrifice (un échange temporairement défavorable) à un moment clé de la partie.
- La dette technique "endémique", c'est plutôt comme perdre ses pièces les unes après les autres, et courir à la défaite.
A quoi reconnaît-on qu'une équipe fait des "emprunts techniques" temporaires afin de s'assurer un avantage (également temporaire) plutôt que de s'endetter jusqu'au cou ? Il suffit d'observer ses pratiques, et d'écouter ce qu'elle répond à ces questions:
- Avez-vous un standard documenté que vous pouvez afficher, ou expliquer via une session en binôme ?
- Avez-vous des tâches de recouvrement prévues pour les "emprunts" techniques en cours ?
- Les tâches de recouvrement s'écoulent elles au même rythme que les tâches standards de développement ?
A l'inverse, à quoi reconnaît on une équipe engluée dans la "dette technique" ? Voici des symptômes qui ne trompent pas:
- Sur le tableau de l'activité de l'équipe, les tâches de recouvrement sont définies en priorité basse, et s'accumulent de semaine en semaine.
- Des graphiques détaillés affichent les résultats des outils d'analyse automatique du code, comme la complexité cyclomatique ou le taux du couverture du code par les tests.
- Quand on l'interroge sur ce pattern, l'équipe voit la dette technique comme un problème, et non comme une solution.
Alors que faire?
Si votre équipe vous semble aux prises avec un problème général de qualité, vous pouvez vérifier quel usage elle fait généralement du terme "dette technique". C'est un bon signal d'alarme. Et si l'alarme sonne en effet, que faire ?
Provoquez un temps d'arrêt pour établir un dialogue autour de ce problème. Vous ne pouvez pas mener un développement logiciel à coups de dettes techniques répétées, et encore moins en vous appuyant sur du code de mauvaise qualité.
Demandez à votre équipe de décider quels standards elle veut appliquer dans son travail. Rendez le standard explicite. Pour cela il ne suffit pas de produire un document mais il faut confronter régulièrement les écarts à ce standard, au moyen de revues de code régulières, facilitées et documentées, ou bien par exemple en adoptant la pratique du pair programming.
Mesurez, au cours des revues, ce que l'équipe dénote comme des défauts de qualité. Tenez à jour le nombre de défauts relevés par revue, afin de vérifier que les actions prises remédient au problème de qualité.
Travaillez sur les facteurs de "dette technique", c'est à dire sur les pratiques de l'équipe, et non sur le code endetté lui même. La dette technique "endémique" est un dégât. Travailler seulement sur les dégâts sans tenter de changer les facteurs, c'est comme tenter d'écoper sans rechercher les voies d'eau. Aucun "gestion de la dette technique" ne permet de remédier à l'absence des pratiques de base du développement: testss unitaires systématiques, revues de code.
Mettez en place des formations, des groupes de lecture, des expérimentations visant à mieux connaître et mettre en oeuvre des pratiques de qualité.
Et que ne faut-il pas faire?
Ne pointez pas du doigt. Ne blâmez pas vos équipiers pour la façon dont ils traitent le problème ou pour leur usage plus ou moins approprié du terme "dette technique". Il y a une image de paresse apparente dans certaines équipes en butte avec des problèmes de qualité, dans lesquelles pourtant même les moins courageux travaillent jusqu'à 10 heures par jour, tous les jours. Il y a en effet deux sens au mot courage: ce peut être le courage de ne pas reculer devant la peur, ou bien celui de ne pas reculer devant l'effort. Si votre projet est "complètement endetté", le courage qui manque probablement, ce n'est pas celui de travailler plus dur, c'est celui de mettre un terme à la fuite en avant et de commencer à investir une partie du temps sur l'amélioration des pratiques. C'est à dire le courage de dire "non".
Bon courage!