La dette technique

Le déroulement d’un projet suit rarement le cours d’un long fleuve tranquille. De nombreux évènements demandent de prendre des décisions, pour ajuster la trajectoire du projet. A la fin, même si les livrables respectent les critères d’acceptation, ces nombreux changements peuvent impacter la qualité du travail réalisé. Ces écarts volontaires ou pas, visibles ou pas, sont regroupés sous le terme de « dette technique ». Nous allons dans cet article aborder cette notion, ainsi que ces causes, et ses conséquences.

La dette technique

Définition

Le terme de « Dette technique » (Technical debt) a été créé en 1992 par Ward Cunningham. C’est une métaphore, inspirée du concept de dette financière, appliquée au contexte de développement logiciel. La dette technique désigne l’ensemble des efforts qui devront être fournis ultérieurement, pour compenser la mauvaise qualité des livrables.

Dette financièreDette technique
Mensualités = Capital + intérêtsCapital = Architecture / code de mauvaise qualité
Intérêts: les erreurs à corriger
Plus le capital est important, ou moins le capital est remboursé, plus les intérêts sont élevésPlus la qualité du code est mauvaise, et plus nous étendons ce code, plus l’effort pour corriger les erreurs sera important

Il existe de nombreuses variantes de cette définition. J’aime bien celle donnée par Victor Szalvay dans un article de ProjectManagement.com:

Technical debt describes the cumulative consequences of cutting corners in software development (Victor Szalvay - Technical Debt for PMs - ProjectManagement.com).

Tout comme les dettes financières, les dettes techniques ne sont pas obligatoirement mauvaises pour l’entreprise. Une dette répondant à un besoin de « time-to-market » peut être décidée dans l’espoir d’un gain futur.

La dette technique peut être considérée comme

  • « visible » lorsqu’elle regroupe l’ensemble des défauts qui ont des effets visibles par les utilisateurs,
  • « invisible », si elle regroupe les défauts, qui ne sont pas visibles par les utilisateurs (mauvaise qualité du code, ou complexité structurelle de la plateforme).

Avoir de la dette est inévitable. Comme le dit Eric Higgins dans son article: The technical debt is like Tetris: you can’t win. You can only control how quickly you lose (Vous ne pouvez jamais gagné. Vous pouvez seulement contrôler à quelle vitesse vous allez perdre).

Les causes de la dette technique

La dette technique peut avoir de très nombreuses causes:

  • le budget limité d’un projet, ou de fortes pressions sur les dates de livraison, peuvent conduire une équipe d’architecture et/ou de développeurs à prendre des raccourcis, et livrer quelque chose « qui tourne », sans trop regarder comment cela tourne,
  • Un manque de compétences ou de formation sur le sujet traité, peut conduite à l’utilisation de mauvaises patterns,
  • La sélection de profils qui ne sont pas en adéquation avec les besoins,
  • La sous-estimation de la complexité du sujet, qui conduit à une architecture simpliste,
  • Au contraire, un sur-engineering conduisant à un design beaucoup trop complexe,
  • Pas de revue de code,
  • Insuffisance de tests, ou couverture incomplète de ces tests,
  • … …

Le quadrant de Martin Fowler (TechnicalDebtQuadrant), propose une méthode de catégorisation de ces causes:

Imprudent/dangereuxPrudent
Dette délibéréeNous n’avons pas de temps pour s’occuper du designNous devons livrer, et assumer les conséquences ultérieurement
Dette involontaireComment cela il faut des tests automatiques ?Maintenant nous savons comment nous aurions du faire ?

Exprimée avec un peu plus de détails, ce quadrant peut prendre cette forme:

Imprudente / excessivePrudente / Modérée
Dette délibérée / intentionnellePression économique, ou pression sur les délais
  • Décision de faire du quick&dirty en raison des contraintes de temps.
  • Pas le temps de faire le design,
  • de choisir les bonnes patterns,
  • ou la bonne technologie
Livraison délibérée d’une version, dont on connait la mauvaise qualité, en assumant les conséquences ultérieures (Réusinage différé).
Dette involontaire / non intentionnelleIgnorance des bonnes pratiques (même les plus basiques),
  • Pas de gestion de la qualité (ou gestion défaillante),
  • Sous-estimation des tests,
  • Processus de développement non structurés,
  • Documentation négligée,
  • Over-engineering (architecture ou code trop complexe)
Dette quasiment inévitable: ce n’est parfois qu’à la fin d’un développement complexe, que l’on se rend compte de ce que l’architecture, ou les patterns auraient dû être.

Différents types de dette

La dette technique ne concerne pas uniquement le code, mais l’ensemble des aspects d’une plateforme.

L’architecture

Cette dette touche la structure / le design des plateformes, et impacte, par exemple, les aspects de performance, ou de fiabilté. Les causes de ce type de dette sont multiples:

  • La sous-estimation de la complexité,
  • Une non compréhension des besoins,
  • Un manque de connaissance des architectures logicielles,
  • Le manque de temps (interdisant des Proof Of Concept, par exemple).

Ce type de dette est en général, assez difficile et coûteux, à corriger. Les corrections passent souvent par des audits, internes ou externes, et/ou l’utilisation d’experts.

Le code

Nous parlons ici de qualité du code. Les causes de cette dette sont souvent liées à des négligences: pas de revue de code, non-respect des patterns, … Le ré-usinage est en général, l’unique réponse pour réduire cette dette.

L’infrastructure

Ce type de dette porte sur l’environnement opérationnel de la plateforme. On trouve, par exemple, des difficultés de mise à jour, un manque de monitoring, un manque de préparation des équipes opérationnelles … Ces défauts conduisent finalement à la non-détection d’incidents, une difficulté à résoudre ces incidents, et donc à un niveau de disponibilité insufissant. Les causes sont multiples, mais elles sont principalement dûes à un manque de préparation de la phase opérationnelle.

Les tests

La qualité des livrables est en général évaluée par le taux de tests réussis. Des tests incomplets, ne couvrant pas l’ensemble du domaine fonctionnel, ou ne couvrant pas les prérequis non-fonctionnels, conduisent à la non détection de défauts, alors que les livrables sont considérés comme valides.

Réduire cette dette passe par une automatisation des tests, la mise place de processus de suivis, et de correction (notamment de la couverture fonctionnelle des tests).

Les problèmes posés par la dette technique

Globalement, accumuler de la dette technique impacte deux aspects principaux du cycle de vie d’une application:

  • La maintenabilité: Après le projet, la maintenance d’une application fait partie des tâches régulières à la fois des équipes opérationnelles, et des équipes de développement. Cette maintenance peut être corrective (celle qui consiste à corriger les bugs), ou adaptative (celle qui consiste à faire tourner l’application sur les couches technologies récentes). Plus cette maintenance est conséquente et difficile, plus les efforts qui lui sont consacrés seront importants.
  • L’évolutivité: Une fois livrée, une application est appelée a évoluer. Une code ou une architecture endettée rendront les évolutions plus difficiles, plus longues. D’une part, les efforts demandés au niveau des équipes de développement seront plus importants, d’autre part, les délais pour livrer les nouvelles fonctionnalités vont s’allonger. Les évolutions de l’application devront faire eux-mêmes faire appel à des compromis, ou vont conduire à des développements du type verrues.

J’ajouterais un troisième aspect, induit par les deux autres: l’adoption. En effet, même si dans une premier temps une application endettée répond aux besoins, les durées nécessaires à la correction des bugs, ou à l’ajout de nouvelles fonctionnalités, peuvent finalement conduire les utilisateurs, à délaisser cette application, ou à l’utiliser de façon détournée. Cela peut conduire à l’utilisation d’applications concurrentes.

Résumé

La dette technique, avec ses causes et ses conséquences peut être résumée de la façon suivante:

Figure 1: La dette technique
Figure 1: La dette technique

Quelques commentaires

Dette technique et qualité des livrables

Dans une approche de gestion de projet « traditionnelle » le chapitre « Qualité » se focalise sur l’alignement des livrables avec les critères d’acceptation. Le respect de ces critères est vérifié par des tests qui se focalisent, la plupart du temps, sur les aspects extérieurs et fonctionnels.

C’est à partir de là que la notion de dette entre en jeux:

  • Les parties prenantes peuvent prendre la décision de déployer un livrable malgré des bugs constatés,
  • Un livrable répondant aux critères d’acceptation, peut malgré tout cacher une structure, ou un code de mauvaise qualité:
    • La structure peut être trop complexe, donc difficile à maintenir, ou à étendre,
    • Les patterns utilisées peuvent générer des limitations qui ne seront visibles qu’au moment du passage à grande échelle, …

Tous ces cas sont de la dette technique, c’est-à-dire des défauts qu’il faut consigner, suivre, et supprimer. Dans vos projets, combien de Proof of Concept (PoC) sont devenus des Minimum Viable Product (MVP) ou même des 1ère versions ? Ces v1 fonctionnent, rendent le service qu’elles sont censées rendre, mais combien doivent être finalement ré-écrites intégralement, en raison d’une structure inadaptée ?

La dette technique offre donc une couverture plus large de la notion habituelle de qualité: d’une part en traçant les défauts externes, et d’autre part, en ciblant les défauts « internes ».

En dehors des projets

Jusqu’à présent, nous avons parlé de dette technique, dans le cadre de projet de développements informatiques. Mais ce concept peut-être utilisé/généralisé, et être employé d’en d’autres domaines.

L’obsolescence, par exemple, qu’elle soit matérielle ou logicielle, est une dette technique: ne pas mettre à jour une plateforme est un choix. Une entreprise peut décider de ne pas mettre à jour une infrastructure, ou une application, parce que la priorité est portée sur le développement de nouvelles applications / fonctionnalités. Cette logique répond à des pré-occupations de courts termes. Mais à long terme, cette entreprise sera confrontée à une dette qu’elle va devoir gérer

  • du matériel qui n’est plus supporté par son constructeur, ou non compatible avec les dernières briques technologiques,
  • une pile logicielle qui ne répond plus aux normes actuelles, générant des difficultés d’intégration avec d’autres applications,
  • du matériel et/ou des piles logicielles qui ne sont plus mises à jour, et qui sont donc vulnérables à des attaques (problèmes de sécurité),
  • le maintien d’équipes dédiées à cette plateforme, car l’application demande des connaissanes différentes des autres applications,
  • une non-conformité vis-à-vis de normes, ou de réglementation.

Dans tous les cas, la plateforme tourne, et rend le service qu’elle est censé rendre, mais l’effort et les coûts nécessaires à sa maintenance deviendront de plus en plus importants.

Maîtriser / contrôler la dette technique

Les paragraphes précédents vous ont convaincu je l’espère, de la nécessité de maîtriser la dette technique. Nous allons voir maintenant, comment le faire.

Etape 1. Prendre conscience de la dette, et la mesurer

Cela peut paraître assez trivial, mais l’une des premières étapes est de reconnaître que nous avons, ou pouvons avoir de la dette technique. Une fois cette prise de conscience effectuée, il faut mettre en place de quoi identifier / mesurer et tracer cette dette technique. Et enfin, il faut définir quel est le niveau de dette acceptable, c’est-à-dire à partir de quand, le niveau de dette va impacter le projet.

La mise en place de ces mécanismes implique une sensibilisation auprès des équipes projet, mais également auprès des parties prenantes.

A partir de là, la maitrîse de la dette technique passe par

  • réduite la dette existante,
  • limiter l’apparition de nouvelles dettes (sur la partie invisible).

Etape 2. Réduire la dette existante

La stratégie a adopter pour réduire la dette technique, dépend en grande partie de l’ampleur de cette dette.

  1. Une dette contenue va conduire à un réusinage du code ou du design, et ces actions seront incluses dans le backlog,
  2. Une dette plus importante nécessitera des travaux de plus grandes ampleurs: cela peut passer par des audits, des sessions de travail (workshops), pour définir la stratégie de réduction de la dette (remédiation),
  3. Au delà d’un certain niveau d’obsolescence, il devient impossible de transformer la plateforme, car les opérations nécessaires deviennent trop complexes, et trop coûteuses. On parle alors de Dette technique endémique. Résorber cette dette consiste alors à remplacer la plateforme existante, et donc de se lancer dans de vastes chantiers de modernisation.

Figure 2: Stratégie de réduction de la dette
Figure 2: Stratégie de réduction de la dette

Intéressons-nous aux cas 1 et 2: Les opérations nécessaires à la réduction de la dette sont souvent intégrées dans le backlog, au même titre que les nouvelles fonctionnalités (user stories). Donc, comme pour toutes tâches d’un sprint, ces tâches doivent être priorisées, et planifiées.

Priorisation

La plupart des méthodes de priorisation peuvent être utilisées. Vous pouvez partir, par exemple, sur un poker planning pour estimer les éléments de la dette, sur les deux axes de valeurs : complexité technique et impact. Vous pouvez également partir sur des méthodes plus génériques comme MoSCoW, la matrice d’Eisenhower, le modèle Kano, …

D’une manière générale, les critères à prendre en compte sont

  • La criticité: que se passe-t-il si la correction n’est pas faite ? Quel est l’impact sur les développements du projet ?
  • Les prérequis: la tâche peut-elle être réalisée immédiatement, ou nécessite-t-elle des prérequis ?
  • L’impact: Quel bénéfice apporte la suppression de cet élément de dette ?
  • L’effort: Combien de temps prendra le développement ? Combien de développeur dois-je dédier ? Quelles sont les connaissances requises ?
  • Les risques! Quels pourraient être les effets négatifs possibles ? Quel est le niveau de confiance pour la réalisation du développement ?

Planification

Comme indiqué précédemment, les éléments de la dette font partie du backlog. La question est de savoir quelle proportion des sprints doit être dédiée à ces tâches. D’une manière générale, il est déconseillé de dédier des sprints entiers à la réduction de la dette.

Philippe Krutchen propose dans son article What colours is your backlog, une composition des backlogs, basée sur un quadrant de quatre couleurs (figure 3):

  • Le vert: Représente les nouvelles fonctionnalités (la valeur ajoutée)
  • Le jaune: Montre les aspects techniques à résoudre,
  • Le rouge: Désigne les défauts identifiés (les bugs, ou les défauts externes),
  • Le noir: Regroupe tous les éléments de la dette technique (défauts internes).

Figure 3: Les couleurs du Backlog
Figure 3: Les couleurs du Backlog

Les quadrants s’appuient sur deux axes:

  • La valeur,
  • La visibilité de cette valeur vis-à-vis des parties prenantes externes à l’équipe (valeur “métier”), ou seulement par l’équipe.

La story “technique” s’applique lorsque:

  • il y a une décision technique à prendre sur la façon de réaliser une user story,
  • il y a un risque technique que l’on veut lever avant la réalisation d’une user story,
  • des travaux techniques sont nécessaires, pour améliorer la façon dont l’équipe développe ou la qualité : infrastructure, logistique, nouvel outil, formation, refactoring…

Le backlog idéal d’un sprint devrait donc contenir les 4 couleurs, avec plus ou moins de prédominances: La figure 4 nous montre 3 cas possibles (parmi d’autres)

  • dans le cas 1, l’équipe se focalise sur la réduction de la dette, et les aspects architecture. C’est très bien pour réduire la dette, mais ce sont des éléments non visibles par les utilisateurs, donc cela peut laisser l’impression que le projet n’avance pas,
  • dans le cas 2, l’effort porte sur les éléments visibles par les utlisateurs: la résolution des bugs, et l’ajout de nouvelles fonctionnalités. Le projet avance du point de vue de l’utilisateur, mais la dette est négligée,
  • dans le cas 3, le focus porte sur la résolution des bugs, et la réduction de la dette.

Figure 4: Equilibrage du Backlog
Figure 4: Equilibrage du Backlog

Quel que soit le mode choisi, il est déconseillé d’allouer un sprint complet à la réduction de la dette.

Etape 3. Contrôle de la dette

Nous venons de voir différentes méthodes pour réduire la dette. Nous venons de constater également qu’au delà d’un certain niveau, cette dette dveient endémique, et n’est plus gérable. A ce niveau, les moyens à mettre en oeuvre pour la réduire deviennent très importants: nous parlons de véritables projets de refonte, ou de remplacement de la plateforme (dernière colonne de la figure 2).

Il font donc éviter qu’un tel niveau de dette n’apparaissent. Nous allons regarder maintenant, comment contenir la dette technique à un niveau acceptable, dans le cadre d’un projet.

Inclure la dette dans le projet

Tout d’abord, il est important d’inclure cette notion, dès le début du projet:

  • d’une part pour « indiquer » aux équipes du projet que la qualité du design et du code sera suivie au même titre que la qualité des livrables,
  • d’autre part, pour sensibiliser les parties prenantes, au fait que des décisions courts termes peuvent avoir de grandes conséquences ultérieures.

Inclure la notion de dette technique implique la mise en place d’un suivi avec indicateurs, ainsi que d’outils de mesure (qualimétrie du code). Une fois que ces indicateurs sont en place, il suffit alors de définir un niveau de qualité dans le Definition of Done: Un livrable sera considéré comme Fini s’il satisfait aux exigences des utilsateurs, mais également s’il répond aux critères de qualité.

Inclure la notion de dette dans un projet implique également la mise en place d’un processus d’aide à la décision. Prenons deux exemples:

  • Les contraintes d’un projet impliquent une accélération de la mise en production de livrables,
  • Le développement d’un livrable prend du retard, et l’équipe projet demande un sprint supplémentaire,

Si l’équipe projet évalue le coût de l’accélération ou de la livaison immédiate, en partageant avec les parties prenantes la nature de la dette créee, et les efforts nécessaires à sa réduction, alors ces parties prenantes seront en mesure de décider si elles souhaitent privilégier la mise en production, ou le niveau de la dette.

Prêter attention aux profils

Chaque sujet demande des compétences particulières. Hors, dans une équipe, tout le monde n’a pas le même champ de compétences. Il est donc important d’assigner aux membres des équipes de développement, des tâches sur lesquelles ils peuvent exercer ces compétences.

Ce point est valable pour les développeurs, mais également pour les data scientists, architectures, les équipes infrastructure, les équipes opérationnelles, … Donc, le chef de projet doit s’assurer que les équipes sont correctement constituées: pas uniquement en nombre, mais surtout en compétence.

Il faut également considérer la présence d’un « tech lead » dans l’équipe capable de fournir l’expertise nécessaire.

Sensibiliser et former les équipes projet

La dette technique nous dit finalement que la façon dont nous créons les livrables, importe autant que les livrabes eux-mêmes. Cette notion de qualité du code ou du design doit être insuffler aux équipes projet qui, souvent sous la pression et coûts et des délais, sont plus orientées « livraison », que « qualité ».

Cette sensibilisation peut passer par la présence de craftman dans l’équipe (voir l’article Software craftsmanship de Wikipédia en français, ou Software craftsmanship de Wikipedia en anglais. Cet artisan du logiciel aide l’équipe sur les questions de qualité du code, ou sur les choix des patterns.

Comme indiqué précédemment, une partie de la dette vient d’une méconnaissance des patterns, ou des bonnes pratiques. Former les équipes (si nécessaire) contribuera à la production d’un code de meilleure qualité.

Revue et analyse

Les revues d’architecture ou de code apportent un autre regard sur ce qui est produit, et permettent de détecter les potentielles anomalies. Ces revues peuvent être faites manuellement (par les collègues), ou automatiquement quand il s’agit du code (tests de qualimétrie).

Automatisation des processus, et des tests

Les tests sont importants à la fois pour éviter, et détecter la dette

  • Des tests incomplets ne détecteront pas tous les bugs, ou des défauts. Il est donc important d’avoir des tests les plus exhaustifs possible d’un point de vue fonctionnel
  • Les tests couvrants les exigeances non fonctionnelles (NFR, non-fonctional requirements) sont également importants: des tests de charge, et la mesure des performances vont détecter, par exemple, une incapacité de la plateforme de fonctionner en pleine charge.
  • Un PoC (proof of Concept) fait partie des tests qu’il est intéressant de faire dans le cadre du design d’une architecture. Il permet de confirmer qu’un design, optimal sur le papier, l’est bien en pratique.

Donc les tests prennent une part importante dans le contrôle de la dette technique. L’automatisation est un autre contributeur: d’une part, elle réduit les efforts nécessaires à la réalisation des tests, d’autre part, elle systématise toutes les étapes, et les contrôles prévus entre l’environnement de développement, et l’environnement de production.

Conclusion

La dette technique est un concept important, et complémentaire de la notion de qualité dans les méthodes de gestion de projet traditionnelles. Elle introduit , entre autre, la notion de qualité « interne ».

Pour moi, inclure la notion de dette technique dans un projet est intéressant sur plusieurs points:

  • d’abord, cette notion introduit la qualité au niveau du « comment », et pas uniquement au niveau du « quoi »,
  • ensuite, elle oblige l’équipe projet a acquérir des connaissances plus approfondies des déliverables du projet (et ne se contente pas de cracher du code), et d’une manière générale, à ce poser des questions que l’on ne se poserait pas autrement,
  • enfin, elle place le long terme dans l’équation.

Cependant, la dette technique, comme toutes les autres méthodes, souffre d’un problème majeur: elle coûte cher, et prend du temps. Je veux dire, qu’en pratique, la gestion de la dette technique dans un projet suppose l’acceptation du coût de la qualité par les parties prenantes: la priorisation des contraintes projet contre la priorisation de la qualité des livrables, et des coûts à plus longs termes (qui ne sont pas forcement visibles au moment du projet). C’est d’autant plus vrai que les effets de la dette ne se perçoivent pas immédiatement.

Donc le concept de dette technique devient réellement efficace et avantageux, par rapport aux notions classiques de qualité, que si l’on met en face de chaque élément de la dette, les coûts induits, et leurs échéances, ce qui est loin d’être un exercice facile.

Crédits

Références

Commentaires