Comment quantifier l’inflation de la dette technique ?

Article original : How to quantify technical debt inflation | Belay the C++ (belaycpp.com)
Traductrice : Chloé Lourseyre

Si vous travaillez pour une société de développement logiciel, vous vous êtes sans doute retrouvé dans le cas où vous aviez une dette technique à résoudre, mais où vous n’aviez pas l’approbation de votre hiérarchie pour le faire dans l’immédiat. « On verra ça plus tard », comme ils disent. Mais en bon·ne développeur·se, vous savez deux choses : la dette technique est de plus en plus dure à résoudre au fil du temps, et l’impact d’une dette technique stagnante ajoute un surcoût à chaque ajout de code qui est fait entre-temps.

Quand vous essayez d’argumenter que « la dette technique est coûteuse », vous vous retrouvez souvent face à la question « coûteuse de combien ? ». Mais vous n’avez pas de réponse à cela, car (à l’heure où cet article est rédigé) il n’y a pas de moyen connu pour prédire l’avenir.

C’est ce que j’appelle la problème d’Inflation de la Dette Technique, ou TDI (pour Technical Debt Inflation).

Avertissement : Je ne peux pas vraiment résoudre le sempiternel problème de la TDI dans un article de deux mille mots. Ce que je donne ici est un fruit de réflexion, l’ouverture d’un débat, une ligne d’approche pour vous pousser à mener votre propre réflexion sur le sujet. J’espère que vous pourrez l’apprécier.

Qu’est-ce que la dette technique ?

On peut définir la dette technique comme étant une partie du code qui est mal conçue et qui a besoin d’être réécrite pour être efficace. Elle n’a pas d’impact pour l’utilisateur, mais rend le code plus dur à maintenir et cela complexifie le développement de nouvelles fonctionnalités (on se limitera à cette définition pour cet article).

Souvent, elle apparaît quand on choisit une approche à court terme plutôt qu’une solution sur le long terme. Cela coûte plus de temps d’écrire une solution au long terme sur le moment, mais une version à court terme se repaye toujours dans le futur.

Qu’est-ce que l’inflation de la dette technique ?

Une dette technique est coûteuse de deux manières.

Premièrement, elle est coûteuse à résoudre. Corriger une dette technique prend du temps, et puisqu’elle est invisible du point de vue de l’expérience utilisateur et de la hiérarchie, c’est souvent considéré inutile par ceux-ci.

Secondement, il est coûteux de travailler « proche » d’une dette technique. Elles ont très souvent des impacts autour d’elles, dans la manière de développer de nouvelles fonctionnalités ou de les maintenir. Par exemple, une dette technique peut être une interface contre-intuitive, qui nécessite plus de temps pour s’y habituer qu’une interface ergonomique. Autre exemple, si un module est mal rédigé, toute mise à jour en son sein coûtera sensiblement plus de temps que s’il était bien conçu.

L’inflation de la dette technique est le fait que plus on attend longtemps pour la résoudre, plus ces coûts augmentent.

En effet, plus le temps passe et plus la quantité de code affectée sera grande (puisqu’il y aura de plus en plus de code dépendant de cette dette) et plus il sera difficile de la maintenir.

Quel est l’intérêt de quantifier la dette technique et son inflation ?

Mesurer l’amplitude de l’impact d’une dette technique est compliqué. Il est encore plus dur de justifier une telle évaluation à celles et ceux qui approuveront -ou pas- le travail que ça implique.

Si on arrive à concevoir un modèle qui met des nombres sur la dette technique, il sera plus facile de justifier de la nécessité résoudre celle-ci au plus tôt.

On pourrait avancer des arguments comme « Oui, ça nous coûterait trois jours de corriger cette dette maintenant, mais si on ne le fait pas, dans deux ans elle aura, en tout et pour tout, coûté en moyenne deux heures par semaines par développeuse et développeur, pour un total de cinquante jours à la fin de la deuxième année… ». Cela pourrait aider à mettre en perspective la vision de la hiérarchie.

Mais je dois bien admettre que la chose la plus importante ne sont pas les nombres eux-mêmes, mais les arguments qui se basent dessus.

Comment quantifier la dette technique ?

La dette technique est coûteuse à résoudre. La première étape est d’évaluer combien de temps une dette prendrait à résoudre aujourd’hui. Sans ça, on ne pourra pas évaluer l’inflation de ce coût.

Par chance, c’est souvent assez facile à évaluer. En se basant sur sa propre expérience du code, on est souvent en mesure de donner une estimation du temps nécessaire à la résolution d’une dette.

En général, je conseillerais de multiplier toute évaluation raisonnable par deux ou trois, afin de prendre en compte les impondérables.

Si vous travaillez en équipe, il est sage de baser son estimation sur la personne la plus « lente » de l’équipe, car vous ne serez peut-être pas la personne qui résoudra effectivement la dette, et si vous travaillez plus rapidement que vos collaborateurs, l’évaluation risque d’être faussée.

Une fois cela fait, on peut maintenant évaluer l’inflation de la dette technique.

Comment quantifier l’inflation ?

La chose la plus importante à retenir à propos de l’inflation est qu’elle n’est pas linéaire.

En fait, vu qu’il y a deux axes sur lesquels la dette technique augmente (le surcoût de correction et le surcoût d’utilisation), et qu’ils subissent tous deux l’inflation, alors cette inflation est, a minima, quadratique1. Elle n’est pas proportionnelle au temps, mais au temps au carré.

S’il n’y qu’une chose à retenir de cet article, c’est cela : la TDI est quadratique.

Maintenant, comment évaluer (numériquement) cette inflation ?

Un indicateur simple et utilisable est la taille du code. La taille du code tend à augmenter avec le temps, et si on arrive à avoir un modèle qui extrapole la taille du code dans le futur à partir de son évolution dans le passé, alors on pourra estimer la taille du code dans le futur.

Je vous donne un exemple de méthode d’évaluation de la taille du code dans un des addenda.

À partir de là, il suffit d’appliquer un facteur quadratique sur cette évolution pour obtenir une évaluation de l’inflation de la dette. C’est ce que j’appelle le modèle de Croissance Quadratique (ou Quadratic Expansion dans la langue de Sutter).

Formalisation du modèle de Croissance Quadratique

Soit C0 la taille du code à t0.
Soit C1 la taille du code à t1.
Soit D0 le temps estimé pour résoudre la dette technique à t0.
Soit D1 le temps estimé pour résoudre la dette technique à t1.
Soit I01 le temps perdu à cause de l’impact de la dette technique entre t0 et t1.
Soit Δ01 le total de temps cumulé qu’a coûté la dette technique entre t0 et t1.

C0, C1 et D0 sont des valeurs connues.
D1 et I01 sont des valeurs intermédiaires.
Δ01 et l’objectif du modèle.

D1 = D0 × C1 ÷ C0

I01 = Λ × C1 ÷ C0, où Λ est une constante qu’on appellera “facteur lambda”2.

Δ01 = (I01 × D1) – D0

Δ01 = Λ × D0 × (C1 ÷ C0)2 – D0

Pour simplifier le calcul, supposons Λ = 1 (on cherche à évaluer un ordre de grandeur, pas à avoir une mesure précise), ce qui donne

Δ01 = D0 × ( (C1 ÷ C0)2 – 1 )

Exemple

Vous avez une dette technique conséquente à résoudre. Votre supérieur hésite à la retarder de six (pour des raisons de jalon de livraison). Vous lui dites que ça coûterait du temps en plus de la reporter, et iel vous demande de quantifier à quel point.

À l’heure actuelle, la fonctionnalité concernée est composée de 21,6 milliers de lignes de code. Il y a trois mois, elle était composée de 17,8 milliers de lignes. Le code a donc gonflé de 3,8 milliers de lignes dans cet intervalle. Cependant, votre équipe (composée de quatre développeur·se·s) vient de se voir renforcée avec un nouvel arrivant, ce qui fait un total de cinq devs. Donc au cours des six prochains mois, on peut estimer que le code grossira d’environ 9,5 milliers de lignes supplémentaires (38×2×1,25).

Votre estimez qu’il faudrait une semaine entière (5 jours) pour résoudre la dette technique.

C0 = 21.6k

C1 = 31.1k

D0 = 5 jours

Δ01 = D0 × ( (C1 ÷ C0)2 – 1 ) ≈ 5.4 jours

Conclusion : selon le modèle de croissance quadratique, l’attente coûterait environ cinq jours et demi supplémentaires.

Vous annoncez donc à votre hiérarchie que, compte tenu de la productivité de l’équipe, attendre six fera plus que doubler le temps perdu à résoudre la dette (en incluant sa correction et le temps perdu à la maintenir).

Les limites de ce modèle

Ce modèle a de grosses limitations.

  • Premièrement, le calcul n’est pas transitif. E.g. Δ02 ≠ Δ01 + Δ12. Cela reflète le fait que plus on porte son regard loin (0 → 2), plus le coût de la dette est incertain. Mathématiquement, il faudrait refléter cela avec un intervalle de confiance.
  • Évaluer et extrapoler la taille du code est souvent faisable, mais pas toujours trivial.
  • Surtout, ce modèle n’a jamais été démontré en pratique.

La question à un million d’euros

Il y aurait bien, en théorie, une manière d’évaluer mathématiquement la problématique TDI : en agrégeant des données recueillies sur des centaines de projets à travers les années. Mais ce n’est pas une tâche simple, sinon impossible. En voici les raisons :

  • Cela voudrait dire ingérer dans le code détenu par des sociétés privées.
  • Même en rétrospective, il est complexe d’évaluer l’impact qu’a eu une dette technique.
  • L’étude prendrait des années, sinon des décennies à être complétée, car les impacts d’une dette technique se mesurent dans le temps.

Avec ça en tête, agréger des données réelles dans une étude sérieuse semble impossible. Mais peut-on élaborer un protocole de plus petite échelle qui pourrait nous aider à résoudre la problématique de la TDI ? Ça mérite réflexion.

Conclusion

Je le redis, pour éviter toute ambiguïté : le modèle de Croissance Quadratique est une manière limite, peu précise et non-scientifique d’évaluer l’inflation de la dette technique, mais elle permet d’avoir un ordre de grandeur cohérent en faveur d’une refonte tôtive du code.

J’espère que ce sera le prélude d’étude plus sérieuse sur le problème de la TDI.

Souvenez-vous qu’évaluer le temps « perdu » d’une dette technique existante est loin d’être trivial et qu’un protocole d’évaluation est impossible à petite échelle.

Mais j’espère que ça vous aidera à avoir une idée plus nette du coût concret des dettes techniques.

Merci de votre attention et à la prochaine !

Article original : How to quantify technical debt inflation | Belay the C++ (belaycpp.com)
Traductrice : Chloé Lourseyre

Addenda

Comment évaluer la taille du code? Un exemple

Avec Git et un shell Linux, vous pouvez facilement évaluer la taille du votre code.

git ls-files Liste tous les fichiers.

grep -E '\.(cpp|h|hpp)$' est un filtre sur les fichiers de source et d’en-tête.

wc -l compte le nombre de lignes.

Voici la commande complète :

git ls-files | grep -E '\.(c|cpp|h|hpp)$' | xargs -d '\n' wc -l

(NB : xargs permet d’alimenter la sortie dans la commande  wc. L’option -d '\n' est présente pour échapper les espaces dans les noms de fichier)

Alternativement, vous pouvez utiliser wc -m à la place de wc -l pour compter les caractères au lieu des lignes. C’est un peu plus lent et moins intuitif, mais à mon avis une meilleure métrique que le nombre de lignes.

Pour que le résultat soit plus lisible, vous pouvez faire

grep -E '^ *[0-9]+ total$' pour récupérer uniquement la ligne de total.

sed -r 's/^ *([0-9]+) total$/\1/' enlève les informations superflues.

La commande complète est désormais :

git ls-files | grep -E '\.(c|cpp|h|hpp)$' | xargs -d '\n' wc -l | grep -E '^ *[0-9]+ total$' | sed -r 's/^ *([0-9]+) total$/\1/'

Si vous avez plusieurs sous-modules, vous pouvez :

Ajouter --recurse-submodules pour que l’opération soit récursive.

awk '{s+=$1} END {print s}' somme les valeurs de totaux.

Ligne de commande finale :

git ls-files --recurse-submodules | grep -E '\.(c|cpp|h|hpp)$' | xargs -d '\n' wc -l | grep -E '^ *[0-9]+ total$' | sed -r 's/^ *([0-9]+) total$/\1/' | awk '{s+=$1} END {print s}'

Notes

  1. C’est basé sur cette idée : puisqu’il y a deux coûts qui augmentent et que ces deux coûts sont entremêlés, leur combinaison est multiplicative plutôt qu’additive. Cela fait que, d’après moi, l’inflation est quadrative.
  2. Λ représente à quel point le reste du code dépend de la dette technique. Plus l’impact est important, plus Λ sera grande, et donc plus I01 sera grand à son tour. Pour des raisons de simplification, Λ est ici considérée constante.
  3. Est-il seulement possible de concevoir un protocole qui permettrait d’évaluer la justesse de n’importe quel modèle de TDI ? Puisqu’on ne peut réaliser qu’une des deux actions (résoudre la dette dans l’instant ou la résoudre plus tard) il n’y a aucun moyen d’évaluer avec certitude le temps qu’aurait pris l’alternative. De plus, le temps nécessaire pour résoudre une dette dépend des compétences de la personne qui la raison et, il faut bien l’avouer, de la chance. En plus de cela, le modèle est conçu pour inclure un risque, ce qui signifie que l’inflation estimée sera grande pour y inclure ce risque. Il n’y a (à ma connaissance) aucun moyen de vérifier ce genre de représentation abstraite.

Laisser un commentaire