BT

Diffuser les Connaissances et l'Innovation dans le Développement Logiciel d'Entreprise

Contribuez

Sujets

Sélectionner votre région

Accueil InfoQ Articles Gérer la dette technique

Gérer la dette technique

La dette technique est généralement vue comme une mauvaise chose; quelque chose qui devrait être évitée ou soldée le plus vite possible.

Devriez-vous la voir ainsi? Nous ne le pensons pas. Premièrement, nous comparons la dette technique à une dette financière, expliquons sa similitude avec le design stratégique et quelles sont ses parties prenantes. Ensuite, nous listons les possibilités pour identifier la dette technique dans votre code. Dette dont vous devrez peut-être vous occuper.

Enfin, nous décrivons les différentes façons dont un projet peut rembourser sa dette technique et ce qu'il faut prendre en compte pour savoir s'il vaut mieux rembourser la dette ou plutôt payer les intérêts.

Qu'est-ce que la dette technique ?

Les développeurs ont le choix d'implémenter de nouvelles fonctionnalités de 2 façons: l'une est de le faire rapidement et de manière désordonnée, ce qui rendra tout changement futur très difficile. L'autre est une solution propre et élégante, qui prendra plus de temps à implémenter, mais rendra des changements futurs plus faciles (cf. Martin Fowler). Cependant, pourquoi les sponsors d'un projet accepteraient un coût plus grand pour une implémentation propre d'une fonctionnalité si la même fonctionnalité implémentée avec du code sale, peut rendre le même service et coûter moins cher? Pourquoi devrait-il dépenser de l'argent sur une couverture de tests automatisés ? Les test ne sont pas des fonctionnalités et ne livrent donc aucune valeur au business!

Bien que du code sale ou du code sans tests fonctionne parfaitement pour le client et délivre la fonctionnalité souhaitée, cela mènera à un socle de code incontrôlable, des développeurs extrêmement spécialisés et finalement à un logiciel peu flexible. Une certaine quantité de code sale peut amener tout un département d'ingénierie à un statut quo.

La métaphore de la dette Technique - Similitude et différences avec une "dette financière"

Ward Cunningham a utilisé la métaphore de la dette technique pour la première fois en 1992 pour discuter de ce problème avec des parties prenantes non techniques. Du code de piètre qualité et sans couverture de tests automatisés peut être comparé à de la dette financière. Ce code est comme un poids financier, qui impose à tous les acteurs - pas seulement aux développeurs - une dette impliquant des intérêts dans le futur. Le capital dû est le coût de refactorer le code vers un design propre, qui permettra des changements futurs plus simples. Les intérêts sont les coûts additionnels, qui devront être payés dans le futur si l'équipe doit travailler avec une base de code sale au lieu d'une bonne.

A la différence d'une dette financière, vous n'avez pas à payer une dette technique. Parfois, la rembourser n'aurait même aucun sens : certaines parties de code sont rarement voire jamais changées ou lues. Par conséquent, la dette technique doit aussi prendre en compte la probabilité des évènements - quelle est la possibilité et la fréquence d'une future modification d'un morceau de code sale? Une autre différence avec la dette financière est que les souscripteurs de la dette technique ne devront pas nécessairement s'acquitter de la dette eux-mêmes, mais plutôt les développeurs qui maintiendront le code plus tard.

De même que la dette financière, la dette technique n'est pas forcément mauvaise. S'endetter pour payer une maison est responsable si vous savez comment vous allez la rembourser. Acheter de nombreux objets de luxe sur votre carte de crédit en sachant pertinemment que vous ne pourrez pas régler l'addition se termine souvent en désastre. Concernant l'industrie du logiciel, la dette technique peut permettre de prendre un avantage lors d'une version initiale et profiter à l'organisation plus que ne coûtera le paiement de la dette technique. Dans le monde financier, la dette est une bonne chose, si le règlement de la dette plus les intérêts est inférieur au retour sur investissement. C'est également vrai dans l'industrie du logiciel. Si vous sacrifiez la qualité interne pour être le premier sur le marché, vous ne serez gagnant que si l'avantage gagné grâce à cette décision est plus élevée que le coût d'être en retard sur le marché mais avec une meilleure qualité interne. Il y a cependant un risque car il est difficile d'estimer en avance ces bénéfices puisqu'il y a un degré d'incertitude.

La dette technique et le Design Stratégique

Le concept de Design Stratégique d'Eric Evans nous donne une idée de la façon de traiter avec la dette technique. Le Design Stratégique dit qu'un système ne peut pas avoir le même niveau élevé de qualité dans chacun de ses composants. Ainsi une équipe peut soit choisir de laisser le hasard dicter quelles parties d'un système ont une bonne ou mauvaise qualité soit activement contrôler cela. Du code sale qui est rarement lu ou touché et n'implémente pas de fonctionnalités critiques, ne doit pas nécessairement être parfait et par conséquent nous n'avons pas à passer beaucoup de temps à le refactorer en un code propre. La question est donc de savoir quelles parties du code devrait être de qualité supérieure ? Il est possible qu'une partie de l'implémentation ait un mauvais design sans qu'au global l'application soit de mauvaise qualité - si un bon design n'est pas requis pour cette partie de l'implémentation. Cette proposition est bien entendu discutable : bien que chaque portion du code n'ait pas besoin d'être de bonne qualité, vous pourriez au final aboutir à un système difficilement à maintenir.

Comprendre le Design Stratégique et la dette technique conduit à une meilleure communication au sein d'un projet et donc à de meilleurs choix des décideurs d'un projet logiciel. Les développeurs pourront comprendre que toutes les fonctionnalités n'ont pas besoin d'être implémenter de façon élégante si cela nécessite trop d'efforts. Les clients pourront également comprendre qu'une solution rapide et sale mène à une dette technique que le projet doit rembourser à un moment. La dette technique est un ensemble de problèmes de qualité logiciel cachés qui comme un iceberg peut conduire à l'échec d'un projet lorsqu'ils font surface. Par exemple, trop de bogues indiquent très probablement qu'il est trop tard pour résoudre efficacement des problèmes de qualité d'un point de vue du coût.

Les acteurs de la dette technique

La dette technique concerne de nombreux acteurs d'un projet logiciel :

  • Les clients dérangés par des bogues ou des fonctionnalités manquantes dues à une faible productivité;
  • Cela mène à un coût additionnel pour le support, qui dérange d'autres personnes de ce département.
  • Des développements ralentis et des problèmes de qualité sont un problème pour le marketing.
  • Des bogues mènent à des patchs fréquents qui contrarient les équipes opérationnelles.
  • De nombreux acteurs agacés ne rendent clairement pas les décideurs heureux - surtout s'il y a de la mauvaise publicité due aux bogues, retards ou problèmes de sécurité.
  • Dernier point mais non des moindre, les développeurs souffrent également. Personne ne souhaite livrer du travail de mauvaise qualité. En addition, personne ne veut reprendre le mauvais travail des autres.

La dette technique est inévitable.

Cependant, pourquoi de nombreux projets ne font-ils pas le boulot correctement pour éviter la dette technique ? Si l'on suppose que les développeurs ne sont pas fainéants et qu'ils sont expérimentés avec les technologies et patterns requis, alors la dette technique est principalement due aux pressions temporelles. Les développeurs espèrent gagner une plus grande productivité à court terme avec une implémentation rapide et sale et abaisser les coûts de la version courante - bien conscient que cela pourrait affecter la productivité et les coûts des versions futures. L'équipe ne peut cependant jamais être sûre que cela amène en fait à une productivité plus grande ou à des coûts plus bas au sein de la version courante. Il est possible que les défauts des raccourcis fassent surface plus rapidement que prévu et que l'équipe ait à payer des intérêts plus tôt que prévu.

Malgré tout, en tant que développeur nous ne voulons généralement pas que des raccourcis affectent ou ne compromettent la qualité. Parfois les facteurs externes font que l'on doit faire les choses rapidement au sein d'une version, parce que sans cela il n'y aurait pas de version suivante. Ou alors l'équipe suppose que ce code ne sera pas lu ou changé souvent. Le Design Stratégique abordé précédemment permet clairement de faire des compromis sur la qualité. Dans ces cas, du code propre pourrait-être de trop.

Ainsi, nous comprenons que la métaphore de la dette technique aide tous les acteurs à discuter des problématiques de code de faible qualité qui pourrait sans cela être découvert trop tard. Les dommages résultants d'un code de mauvaise qualité et l'accroissement de la dégénérescence de la qualité sont très bien symbolisés par cette métaphore de l'intérêt. La métaphore a toutefois des limites : toutes les dettes techniques ne doivent pas être remboursées. L'équipe ne connaît pas le montant de cette dette technique et quand elle doit être remboursée. La personne qui souscrit la dette n'est pas nécessairement la personne qui la paie, c'est souvent quelqu'un d'autre. Ça me dirait bien dans la vraie vie !

Identifier la dette technique

Un des principaux problèmes de la dette technique est qu'elle n'est pas évidente. N'importe qui peut lire le solde d'une dette sur un bilan comptable. Comment une équipe peut-elle reconnaître une dette technique ? Quels en sont les indicateurs ?

  • Une "odeur" se manifeste généralement dans les déclarations des membres de l'équipe : "Le seul qui peut changer ce code c'est Carl", "Copier-collons ce code", "Si je touche ça, je casse tout" ou alors trop de TODOs et de FIXMEs dans le code (élégamment décrit par Nico Zazworka).
  • Les équipes Scrum ont une vélocité. La base logicielle a probablement trop de dette technique si la vélocité se réduit alors que l'équipe et les facteurs externes n'ont pas changé.
  • Un logiciel vieillit. Un indicateur de la dette technique est un système qui utilise de très vieilles bibliothèques qui ne sont plus maintenues ou qui ont une nouvelle version qui permet une meilleure productivité (ex: EJB2 vs EJB3). Dans le pire des cas, ces bibliothèques sont si vieilles que les développeurs de ces librairies ne fournissent plus de support pour celles-ci.
  • Mesurer la dette technique automatiquement est partiellement possible. Correctement configuré, des outils comme Sonar, SonarJ ou Structure101 permettent de trouver d'importantes violations de bonnes pratiques. Comme ce billet de blog le montre, ce n'est pas une solution finale mais une très bonne solution. Avec Sonar vous vous assurez que les développeurs suivent d'importantes métriques telle que les classes et les méthodes ont des tailles appropriées et une faible complexité cyclomatique. Des outils comme structure101 vous aident à trouver des problèmes de structure. Cela inclue des dépendances cycliques. Si deux éléments dépendent l'un de l'autre, un changement dans les deux éléments va potentiellement affecter l'autre élément. Ces deux éléments ne peuvent être changés qu'ensemble - bien qu'ils devraient en fait être séparés et développés indépendamment. De plus, Structure101 trouve du code complexe : tout repose sur les dépendances entre les éléments. Un système est très complexe à comprendre et donc à maintenir si les classes ou paquets ont trop de dépendances les uns avec les autres. Si un développeur veut faire un changement il doit comprendre de nombreuses classes et paquets et doit considérer de nombreuses dépendances. Ces problèmes pointent des challenges clés de l'architecture.
  • Des outils de mesure de couverture de tests permettent de connaître la quantité de code couverte par les tests automatiques. Cette mesure doit être utilisée avec soin puisqu'il n'y a pas d'instructions génériques. Habituellement, une couverture supérieure à 90% indique qu'il y a assez de cas de tests. A l'opposé, une couverture inférieure à 75% peut indiquer de sérieux problèmes.
  • Il y a malgré tout de nombreux cas dans lesquels les systèmes ont une dette technique qui ne peut pas être mesurée directement dans le code, par exemple des solutions maladroites, de mauvais choix technologiques, un design bien exécuté mais incorrect pour le système ou simplement des raccourcis maléfiques qui ne peuvent pas être détectés simplement par ces outils. Dans ces cas, la dette technique doit être mesurée différemment : le nombre de bogues par version croît rapidement, la vélocité diminue de façon permanente, l'équipe est sous un état de stress extrême vers la fin d'une version.
  • Un autre indicateur est de fréquents problèmes en production. Cela signifie que les problèmes dans le système sont si généralisés qu'il n'est plus possible de rendre un service fiable.

Tous ces indicateurs peuvent être mesurés, mais pas toujours directement dans le code. Le plus tôt ces problèmes sont résolus, le moins ils coûtent. Si les développeurs identifient de la dette technique, la communiquent, et rien ne se passe, tôt ou tard les gens en charge du business ressentiront ces problèmes. Cet énoncé montre clairement que la dette technique n'est pas une invention des développeurs qui veulent du code magnifique. C'est un coût tangible et un risque pour un projet. Ainsi, la dette technique doit être rendu visible et possible à gérer. De même que dans la vraie vie, une dette n'est pas nécessairement une mauvaise chose mais doit être utilisée en pleine conscience et correctement. Cela signifie pour les projets que rembourser une dette technique doit être une décision du business. Cela ne doit pas être une simple décision d'un développeur.

Comment peut-on gérer une dette technique?

Nous avons vu que la dette technique peut être ignorée. Même le management non technique du côté client doit avoir un intérêt à gérer la dette technique aussi intelligemment que possible pour obtenir le meilleur équilibre entre succès à court moyen et long terme. Qu'est-ce qu'une équipe doit faire pour éviter de perdre son temps avec un embellissement inutile tout en faisant des décisions pleines de sens pour le business afin d'améliorer la qualité du code.

Des déclarations sans finesse telle que "ne rien faire" ou "même si le code est impossible à maintenir, il faut développer quand même" n'apportent rien.

Nous considérons dans cet article deux approches prometteuses qui ont déjà été utiles au sein de plusieurs projets.

  • Le backlog technique
  • Inclure le coût pour de la dette technique dans les estimations

    Avant cela, nous souhaitons discuter de deux autres processus critiques qui ont du sens dans certains contextes projets:

  • Des tâches tampons de refactorisation

  • Des versions de nettoyage

Une question à laquelle on doit toujours répondre dans les discussions de dette technique est: doit-on payer cette dette technique? Frank Buschmann décrit trois stratégies que nous développerons plus tard:

  • Le paiement de la dette
  • La conversion de la dette
  • Le paiement des intérêts

La tâche tampon

L'équipe créée une tâche tampon par version avec par exemple 10% de temps disponible. Les membres de l'équipe peuvent imputer sur cette tâche de la refactorisation non planifiée. Donc cette tâche est là pour être utilisée pour des problèmes inconnus qui pourraient apparaître dans le futur. Un tel buffer est très facile à planifier et à utiliser. Cela pose toutefois le problème que ce temps pourrait être gaspillé sur du travail sans importance. Un buffer ne force personne à considérer si le temps est employé pour des refactorisations utiles ou non. Les développeurs imputent simplement leur temps en face de cette tâche tampon. Très probablement, le temps alloué à se buffer ne sera pas employé de façon optimale - et particulièrement décider quelles refactorisations seront faites, bien que cela devrait vraiment être une décision du business. Utiliser des tâches tampons signifie malheureusement que ce qui devrait être fait n'est pas vraiment défini.

Des versions de nettoyage de code

Certaines équipes font des versions purement techniques pour améliorer leur socle de code de temps à autre. Cette approche n'est utile que s'il existe déjà une liste avec les refactorisations vraiment nécessaires. Sinon l'équipe risque de perdre du temps sur des refactorisations sans importance. Cette approche doit également être soutenue par le business, car elle peut retarder les nouvelles fonctionnalités. Bien entendu cela signifie que le business doit comprendre ce qu'est la dette technique. Vous devriez penser à faire une version purement technique pour nettoyer le code et retravailler l'architecture seulement si un effort majeur est requis. Par exemple, si certaines parties du code causent des problèmes durant le développement ou l'exploitation, si l'architecture courante ne permet pas de satisfaire les exigences. De tels problèmes ne peuvent pas être résolus avec de petites refactorisations. Une version dédiée au nettoyage du code permettra ces changements plus extensifs.

Il n'y a aucun sens à faire une version de nettoyage après chaque version intense et limitée par le temps qui a créé beaucoup de dette technique. Il n'y a que peu de retour sur expérience avec le nouveau code source donc personne ne peut dire quelle partie du code a besoin d'être améliorée. Le danger est de modifier du code qui n'a pas vraiment besoin d'être améliorer.

Le backlog technique

Le backlog technique est une bonne pratique établie pour définir les paquets de travail purement techniques. Les tâches pour celui-ci sont créées dans un logiciel de suivi ou de gestion des tâches. Chaque tâche contient une brève description technique du changement à implémenter, pourquoi cette tâche est importante pour le projet et dans quelle partie du code le changement doit être fait. Comme pour toute autre tâche, on a besoin d'une estimation du temps nécessaire pour développer une solution correcte. De plus, on a besoin d'estimer l'intérêt de ce code. Une estimation précise est complexe mais souvent une estimation approximative telle que "faible", "moyenne", "forte" est un guide suffisant pour prendre une décision. Enfin, on a également besoin d'une probabilité : quelle est la probabilité que ce code soit lu ou modifié dans un avenir proche?

Cette approche a plusieurs avantages :

  • La dette technique est visible et claire pour tous. Une décision unanime peut être faite au regard de quand et si une tâche de refactorisation devrait être faite, basé sur un effort estimé et sur les impacts futurs de ce changement de code ;
  • Le coût de chaque tâche est facile à suivre ;
  • Il n'y a aucun mélange entre tâches techniques et fonctionnelles ;

Cependant cette approche a également des désavantages:

  • Le client doit décider du backlog et de la priorité à assigner à chaque tâche. Le client ne peut accomplir cela que jusqu'à un certain point en ce qui concerne les détails techniques puisqu'il ne peut pas déterminer l'apport d'une tâche technique sans une connaissance fine du logiciel.
  • De plus, le client peut ne pas vraiment comprendre les bénéfices business d'une tâche purement technique. Dans de nombreux cas, la confiance fera défaut, pourquoi réaliser une tâche technique sans une fonctionnalité pertinente et utile au client. A notre avis, rares seront les cas où le client sera en mesure de décider de cela. Par exemple, pour des cas de mise à jour de version. C'est évident pour de nombreux clients qu'une brique logicielle dans une version dépassée cause des problèmes. La mise à jour ou non doit être décidée au cas par cas en fonction du coût, du risque et de la nécessité de cette mise à jour. Des mises à jour de composants tel que le "Java Runtime Environment" ou d'un mappeur objet-relationnel ne coûte habituellement pas trop cher et ont un faible risque s'ils sont faits régulièrement. Des changements très coûteux tel que le remplacement d'un framework web ou un changement d'une base de données relationnelle vers une solution NoSQL doit toujours avoir des fondements business. Par exemple si la performance ou l'expérience utilisateur ont besoin d'être améliorées. Pour ces besoins, un backlog technique est adéquat. Toutefois, pour de telles tâches vous pouvez aussi créer un projet à part en fonction de l'effort attendu pour la réalisation.

Le backlog technique n'est pas si bien si une nouvelle exigence doit être implémentée dans un code source qui n'est pas conçu pour la recevoir. Dans de tels cas une refactorisation peut être nécessaire. Pour ce faire, vous devez ajouter l'effort supplémentaire de refactorisation dans l'estimation de cette exigence.

L'estimation de travail avec l'effort de la dette technique

La conception stratégique nous a appris que toutes les parties du code n'ont pas besoin d'être de très bonne qualité mais seulement celles dont la capacité à changer amène de la valeur au business ou celles qui ont besoin d'être changées pour d'autres raisons. Ainsi, en ce qui concerne la dette technique d'un code qui ne change que rarement voire jamais, elle peut être ignorée. Il est également important de noter qu'un code ne devrait jamais être refactorisé sans une bonne raison. Donc si une nouvelle exigence apporte une valeur concrète au business alors nous ne devrions jamais implémenter cette nouvelle exigence sur du code mal écrit mais le refactoriser avant. De cette façon, les exigences vraiment importantes pourront être implémentées sur des standards de qualité suffisants. Quand on demande à l'équipe d'implémenter de telles fonctionnalités dans une version, la refactorisation devrait être incluse dans le budget et ensuite implémentée. Bien entendu, il y a des exceptions dont nous discuterons dans la section "Payer ou ne pas payer".

Cette procédure assure qu'il n'y a pas de travail fait pour rendre le code plus beau qui soit inutile, et que la refactorisation est toujours faite en association directe avec une exigence métier. Cela permet au client de discuter et de choisir ses priorités de refactorisation avec l'équipe. Le client peut également décider si une exigence devrait être implémentée sur la base de la dette et des intérêts. Il pourrait également y avoir d'autres facteurs à prendre en compte tel que les délais de commercialisation. Le client pourrait également avoir connaissance des changements futurs de ce code basés sur ces exigences. Il pourrait alors décider de refactoriser le code en un code plus propre pour économiser des coûts futurs.

Des problèmes pourraient survenir si l'équipe rencontre des difficultés avec le code source durant l'implémentation. Alors l'équipe doit décider ce qu'il faut faire: peut-être que respecter la date de livraison avec toutes les fonctionnalités est très important. Dans ce cas, la dette technique et les intérêts qui vont avec doivent être acceptés. Ou tout développement basé sur le code mal écrit est considéré comme un gaspillage et il n'y a aucune pression réelle liée à une date limite. Dans ce cas l'équipe devrait planifier une refactorisation qui causera du retard sur la date de livraison. La décision doit être prise en fonction du contexte et des besoins des clients.

Payer ou pas payer

Nous avons vu que seules les parties importantes du code doivent être nettoyées. Donc le code ne devrait être refactoré que si nécessaire. Cependant il est très compliqué de décider quelle solution est la meilleure pour un scénario spécifique. Franck Buschmann décrit 3 stratégies:

  • Le paiement de la dette: refactoriser ou remplacer le code, le framework ou la plate-forme qui est considéré comme une dette technique
  • La conversion de la dette: remplacer la solution actuelle avec une solution correcte mais pas parfaite. La nouvelle solution a un taux d'intérêt inférieur. Cela peut être une bonne option si une solution parfaite à un coût prohibitif à réaliser.
  • Simplement payer les intérêts: vivre avec ce code, car le coût de la refactorisation est supérieure au sur-coût associé au code non optimal.

    Les Développeurs et les clients doivent décider de cela en fonction du coût, du risque et de l'urgence. En résumé, une refactorisation importante devrait toujours être une décision du business. Un autre facteur important pour payer les intérêts: la fin de vie du logiciel - une refactorisation a-t-elle un intérêt si le système va être développé à nouveau ou retiré du marché bientôt de toute façon?

Conclusion

La dette technique peut être vue comme un raccourci qui fait gagner aujourd'hui du temps, de l'énergie et de l'argent à l'équipe, mais qui pourrait augmenter les coûts futurs. La dette technique ne peut pas vraiment être évitée dans des projets logiciels. Cela n'est cependant pas une mauvaise chose si elle est gérée correctement.

Le faire est compliqué: l'effet d'un code de mauvaise qualité sur de futurs exigences est difficile, voire même impossible à prédire. Cependant, ignorer complètement la dette technique peut avoir des conséquences désastreuses sur le logiciel. Si l'équipe et le client prennent en compte le risque de la dette technique correctement, cela devrait rester gérable. Nous avons présenté différentes façons de répondre à de la dette technique. Chacune de ces options ne devrait être utilisée que dans des contextes bien spécifiques. Il est important d'accepter:

  • qu'il y a toujours de la dette technique
  • que la dette technique n'est pas nécessairement mauvaise
  • que la dette technique ne doit pas nécessairement être (complètement) remboursée dans tous les cas.

Tout remboursement doit être une décision du business. Même si le remboursement est si petit, qu'une consultation du client n'a pas de sens, le développeur doit toujours se demander si une amélioration du code justifie l'investissement en temps et en énergie.

A propos des auteurs

Sven Johann travaille en tant que développeur pour Trifork à Amsterdam. Sven est un utilisateur des pratiques d'extreme programming tel que la programmation par pair, le TDD et les petites releases. Il développe en ce moment un logiciel d'évaluation en ligne pour des écoles en Suisse et aux Pays-Bas basé sur le moteur QTI de Trifork

Eberhard Wolff travaille en tant qu'architecte et directeur technique pour adesso AG en Allemagne. Il se concentre sur Java, l'informatique dématérialisée et l'architecture logicielle. Il contribue régulièrement à des conférences internationales et est l'auteur de nombreux livres et articles.

Evaluer cet article

Pertinence
Style

Contenu Éducatif

BT