Comment gérer la dette technique sur vos projets ?

écrit par Jérémy Génard publié le jeudi 14 février 2019

Définition

Le terme dette technique a été proposé pour la première fois par Ward Cunningham, le créateur du concept de Wiki et de l'eXtreme Programming. Pour bien comprendre la notion, il faisait le parallèle avec les dettes financières. L'idée est que chaque dette permet de résoudre un problème à très court terme qu'il faudra rembourser avec des intérêts. Dans le milieu de l'informatique, les intérêts représentent le coût des opérations permettant de revenir à un code/système stable et maintenable. Lorsque les dettes financières sont trop importantes pour une entreprise, elle fait faillite. Dans le cadre d'une application, la faillite représente simplement la réécriture complète de l'application. La dette technique est alors tellement importante qu'il coûte moins chère de réécrire l'application qu'il en coute de la remettre en ordre. Le dette technique est donc un moyen de représenter le coût des opérations visant à remplacer une solution à court terme par la meilleure solution possible. Le quick-and-dirty ou "à l'arrache" est selon moi, le phénomène qui engendre le plus facilement de dette technique.

Toutes les dettes ne se valent pas

Martin Fowler propose un diagramme, traduit ci-dessous, pour mieux distinguer les sources de la dette technique au sein d'un projet/système :

On peut identifier 4 sources de dettes techniques qui se recoupent dans les problèmes du quotidien d'un développeur :

  1. La dette générée par un comportement imprudent et souhaité. Dans son exemple, Martin Fowler se met à la place d'un manager qui supprimerait le temps dédié à la conception pour "gagner" du temps. A court terme, le manager est heureux, son dashboard est au vert, le budget est consommé pour du développement de features. A long terme, ce genre de dette est désastreuse car il a été demandé explicitement aux développeurs de faire du mauvais code, ceci va induire des coûts de maintenance important en plus de ralentir les futures évolutions. De mon point de vue, c'est ce qu'il se fait de pire en terme de dette et on peut parler de sabordage car l'objectif n'est pas de rendre le projet meilleur dans son ensemble.
  2. La dette générée par un comportement imprudent mais accidentel. Pour comprendre facilement ce cas, imaginez une équipe de développeurs juniors, tout juste sortis de l'école avec beaucoup de bonnes intentions mais un manque d'expérience qui amènera forcément de nombreux problèmes de conception, d'organisation et de qualité. Il est généralement assez facile de prévenir ce type de dette. Encadrer l'équipe par un lead developper ou simplement par un développeur expérimenté suffit à limiter les problèmes. Il est possible de former les équipes aux différentes technologies et aux outils liés au projet. En revanche, ce genre de dette est souvent synonyme de code spaghettis, d'overengineering et est difficile à résorber.
  3. La dette générée par un comportement prudent et souhaité. Cette dette est souvent générée peu de temps avant une mise en production. Avec un exemple simple, il est facile de voir comment nous sommes amenés à produire ce genre de dette. Vous travaillez sur une application qui va révolutionner un marché d'un secteur quelconque. Mais vous apprenez qu'un de vos concurrents a développé une solution similaire qu'il va bientôt mettre en production, vous coupant l'herbe sous le pied. Vous pouvez encore vous en sortir mais à une seule condition, déployer votre application, en premier, en sacrifiant la qualité de votre base de code. Une fois votre solution en production, vous aurez un peu de temps pour vous remettre d’aplomb et repartir sur de bonnes bases.
  4. La dette générée par un comportement prudent mais accidentel. Celle-ci est très simple à comprendre. Vous avez conçu une brique de code l'an dernier, vous revenez sur le sujet et vous vous rendez compte que ce n'est pas terrible. Avec votre nouvelle expérience, vous savez que ce n'était pas un choix judicieux et vous pouvez désormais faire mieux. Ce qui est génial à propos de ce type de dette c'est que vous pouvez appréhender votre gain d'expérience, vous avez quand même produit de la dette mais vous ferez mieux la prochaine fois. Dans le meilleur des cas, vous profitez de vos nouvelles compétences pour corriger, refactorer le code et régler votre dette. Au pire ? Vous avez appris des choses et vous ne recommencerez pas sur votre prochain projet.

Tout ceci pour vous dire qu'il existe bel et bien plusieurs sources de dette technique et chacune nécessite des moyens différents pour être gérer.

Outils de gestion de la dette technique

Bien évidemment, impossible de parler "dette technique" sans évoquer SonarQube. C'est un outil open source qui vous permet d'avoir un dashboard pour vos différents projets. Attention, SonarQube ne fait pas l'analyse de code, il intègre les rapports générés par les moteurs de build (ex : MSBuild dans l'univers .Net) pour vous permettre de faire le suivi de la dette. Ainsi, il peut affecter les bugs, les code smells et les vulnérabilités au développeur à l'origine de l'erreur. Il vous permet de visualiser tout un tas de métriques :

  • Fiabilité
  • Sécurité
  • Maintenabilité
  • Couverture de code par les tests
  • Duplications de code
  • Taille des fichiers, des fonctions, nombres de classes par projets
  • Complexité

En bref, un incontournable lorsqu'on parle de dette technique. Également, il faut garder à l'idée que peu importe l'outil que vous utilisez pour faire le suivi, il n'y a pas de formule magique, ni de solution idéale. Il vous faudra toujours investir du temps dans le paramétrage de l'outil. Encore une fois, toutes les dettes ne se valent pas et selon les équipes et les projets, les règles ne s'appliqueront peut être pas toutes selon la même criticité. Dans le paragraphe suivant, j'évoque un cas concret où nous avons définis deux ensembles de règles : un pour les nouveaux projets et un autre pour les projets Legacy. Nous avons volontairement exclus le CSS et l'HTML de nos analyses pour nos vieux projets. Nous savons tous que corriger du CSS qui a déjà 5-6 ans est une opération très complexe qui peut très vite casser votre application. A contrario, pour tous les projets récents les règles sont volontairement plus strictes afin de garantir une qualité de code supérieure dès le début du projet. Mais tout ceci évolue nécessairement au cours du temps et demande un effort de gestion supplémentaire. Pour aller plus loin, il existe d'autres outils que je n'ai jamais pu utiliser car ils sont sous licence commerciale pour la plupart :

De la théorie à la pratique

Il existe beaucoup d'articles comme celui-ci qui traite de la dette technique. Beaucoup d'explications pour la gérer et la résorber avec assez peu d'éléments concrets.

Description du SI et détail de la dette

Je vais parler d'un cas très concret qui m'aura beaucoup occupé pendant l'année 2018. J'occupe un poste d'architecte et j'ai reçu pour mission de suivre et de faire baisser la dette sur l'ensemble de nos projets, soit 15 projets pour environ 1,5 millions de lignes de code. On retrouve au milieu, des projets tout neufs mais aussi du legacy, du progiciel, etc... un SI plutôt commun avec divers langages aussi, différentes architectures et des équipes projet d'âges et d'expériences très variées. Il y a plusieurs années, un premier mouvement pour résorber la dette avait été lancé avec l'arrivée de SonarQube. Dirigé par quelques développeurs expérimentés, l'effort s'est très vite essoufflé, les équipes ont changé et la dette a très vite repris beaucoup d'ampleur. Et plus elle est grande, plus le chantier est important et souvent, il est plus avantageux de refaire l'application "from scratch". Cette solution n'est pas toujours envisageable.

Qu'avons-nous mis en place ?

Au cours de l'année 2018, on a remis en ordre notre SonarQube et nous avons lancé des réunions mensuelles pour faire le suivi de la dette pour chaque projet. L'idée est simple, donner de petits objectifs facilement atteignables et en cohérence avec la charge du projet. Ainsi, nous réunissons le chef de projet et le lead developper car chacun est garant d'une partie du projet :

  • Le lead developper doit assurer la qualité du code et suivre la production des autres développeurs
  • Le chef de projet doit assurer les coûts du projet ainsi que le respect du planning

De ce fait, ces deux personnes vont directement fixer les objectifs. Et c'est important que ça vienne de l'intérieur de l'équipe et pas de l'extérieur pour plusieurs raisons :

  1. Limiter la pression sur les développeurs. La MOA, les managers et les aléas du projet sont déjà suffisamment pénibles.
  2. Responsabiliser l'équipe.

Pour commencer, le plan d'action doit être simple et rapide à faire. Pour la plupart des projets, nous nous sommes mis d'accord de nettoyer une parties des petits code smells :

  • Accolades manquantes aux blocs if/else, etc...
  • Suppression du code commenté
  • Suppression des variables locales non utilisées
  • Etc...

Les résultats de ces premiers nettoyages ont été très concluant. La plupart des équipes ont compris que de petits gestes pouvaient avoir de gros impacts sur la qualité du code pour un coût presque nul. Et l'ensemble des projets ont même dépassé leurs objectifs ! Comme les équipes ont saisi l'importance de faire attention à la dette technique, nous avons pu demander d'aller plus loin notamment sur des sujets qui peuvent avoir un impact sur le fonctionnement des applications comme de réduire les issues concernant la complexité cyclomatique. Encore une fois, c'est bien l'équipe du projet qui a choisi les points critiques où ils souhaitaient intervenir.

Et les code reviews dans tout ça ?

En parallèle, nous avons fait un travail de relecture régulier via des code reviews. C'est très important d'évaluer régulièrement le code produit pour plusieurs raisons :

  • Observer l'évolution de la qualité
  • Comprendre comment travaillent les développeurs
    • Beaucoup de petits commits très réguliers ou au contraire des gros commits avec beaucoup de code
    • Deux commits : un pour la feature, un autre pour le nettoyage du code
  • Remarquer les erreurs qui reviennent souvent pour faire une réunion/formation autour des points clefs
  • Intervenir au plus tôt car la dette est plus facile à rembourser lorsqu'elle est prise en compte immédiatement

Bilan

Après une année, nous sommes passés d'un total de 100 000 à 66 000 issues sur SonarQube soit un tiers de notre dette technique qui a été corrigée. Il reste encore beaucoup à faire mais désormais nos équipes de développeurs font chaque jour quelques corrections en prenant 10-15min sur leur temps de développement. En conclusion, il faut retenir :

  • Toutes les dettes ne se valent pas
  • Il est important d'identifier les sources de la dette
  • Il faut suivre la dette avec des outils comme SonarQube
  • Fixer de petits objectifs avec les équipes de développement