La dette technique, est-ce une fatalité ? - Compte-rendu du talk de Mickael Wegerich à La Duck Conf 2021

Au bout d'un certain temps de la vie d'un produit (environ 2 ans), les entreprises se retrouvent souvent à se poser cette question : "devons-nous tout écrire, tout recommencer ?"

Pourquoi en arrive-t-on à se poser cette question ? La grande majorité du temps, l'équipe n'arrive plus à maintenir son code, à développer de nouvelles fonctionnalités, elle a de plus en plus de mal à corriger les bugs, etc. Bref, elle s'est fait rattraper par la dette technique.

Mickael Wegerich - Duck conf 2021Mickael Wegerich - Duck conf 2021

Mais qu'est-ce que la dette technique ?

À l'origine, la dette technique est une dette contractée volontairement afin d'accélérer le développement à un instant T. Cette dette doit être remboursée immédiatement après (en réalité cette dette est au mieux partiellement remboursée, au pire pas remboursée du tout). Mais dans le langage courant, cette dette comprend aussi tout ce qui est généré au fil des développements de façon inconsciente par un manque de connaissances et/ou de compétences : c’est de cela que nous parle Mickael (liens de la vidéo et des slides).

Nous sommes acteurs de la détérioration du code

On peut citer 4 causes principales :

4 piliers facteurs de la détérioration inconsciente du code

  1. Choix des technos et architecture SI :
    • La technologie et/ou l'architecture ont été choisies en fonction des modes du moment, pour suivre une mouvance, mais l'équipe ne les maîtrise pas et n'en n'a peut-être même pas le besoin (ex: microservices).
    • L’équilibre entre construire pour aujourd’hui ou construire pour demain est difficile à trouver : soit on fait trop simple et on va au plus basique pour répondre aux besoins du moment sans se poser la question du lendemain (ce qui peut impliquer une complexité supérieure après coup) ; soit on fait trop compliqué dès le départ et on conçoit du code qui ne sera jamais utilisé et du code inutile à maintenir.
  2. Architecture et design de code : le code n'est pas structuré et on se retrouve avec un code compliqué à comprendre, à parcourir. De plus, on peut se retrouver avec un manque de concept métier dans le code : pas de vocabulaire commun entre le métier et la technique, et il faut sans cesse traduire de l’un à l’autre pour se comprendre.
  3. Stratégie de test : difficile de toucher à un bout de code sans casser tous les tests associés. Cela entraîne des refactorings plus longs et douloureux, ce qui peut même freiner l’envie d’améliorer le code.
  4. Organisation : quand plusieurs équipes travaillent sur un même produit, elles finissent par prendre des décisions chacune de leur côté et le produit devient N produits.

À garder en tête : Nos choix nous rattrapent. Et les mauvais plus vite que les autres...

Point d’attention : le métier peut être complexe de par sa nature. Les solutions pour répondre au besoin que l’on cherche à résoudre peuvent être complexes. Essayons donc de ne pas ajouter de complexité superflue dans le code. Mais comment faire ?

Des outils à notre disposition pour nous aider

  • Communiquer !

"Le code est le reflet de notre organisation" Melvin E. Conway (cf autre talk de la Duck Conf sur ce sujet)

Les membres d’une équipe doivent discuter, partager, s’interroger, concevoir et décider ensemble. La communication est un pilier fort qu’il ne faut pas négliger dans une équipe.

  • Faciliter l'écriture de code dès la première ligne

La clean architecture (ou l’architecture hexagonale) aide à atteindre ce but en isolant, dans le code, la partie à valeur ajoutée c’est-à-dire le code métier.

Architecture hexagonale

En plus de structurer le code en séparant la responsabilité de chaque couche, ces patterns d’architecture vont aider à la construction d’une stratégie de test :

  • tester en isolation (test unitaire) le code à valeur ajoutée ;
  • tester en isolation du centre (test d’intégration), les parties de droite et gauche ;
  • tester de bout en bout en traversant toutes les couches.

Il faut aussi savoir que, bien souvent, les tests sont trop couplés au code : en résumé, il y a une classe de test pour une classe de code. Ce qui implique que le moindre refactoring va casser les tests et rendre ce re-travail plus complexe et plus long à effectuer. Une meilleure façon de tester est de tester en unité fonctionnelle, c’est-à-dire que nous allons tester plusieurs classes par transitivité, rendant le code plus flexible.

Découplage des tests

  • Comprendre le métierCitation d'Alberto Brandolini

Les développeurs ont besoin de savoir ce qu'ils sont en train de développer : ils doivent comprendre la problématique que le produit cherche à résoudre.

Sans rentrer dans le détail, voici deux outils qui aident les équipes à s’imprégner davantage du métier et de le faire transparaître dans le code : l’event storming (exploration d'une problématique métier) et le Domain-Driven Design.

  • Prendre de la hauteur

Le partage, la veille, la lecture, les échanges, etc. permettent de ne pas rester sur ses acquis et de continuer d’apprendre, de se cultiver.

Le but derrière tout ça est d’éviter de se battre avec son code et de pouvoir prendre du plaisir ; de penser à demain, à la personne qui va devoir reprendre le code que “vous” avez livré. Cette personne qui sera d’ailleurs vous-même pendant un (bon) moment.

Améliorer la qualité du système va automatiquement motiver l'équipe. C’est un cercle vertueux : l’équipe produit un "beau" code (qualité des développements) → motivation des développeurs → soin du code → pas/peu de bugs en production → utilisateurs et clients contents → volonté de produire du “beau” code, etc.

Demain, retour à la réalité

Tout d’abord, prenez le temps : "Le code est un marathon, pas un sprint".

Nous avons tendance à courir après les US (pour tenir des engagements sûrement trop ambitieux). Résultat : développements rapides → génération de dette technique → dette non remboursée en totalité → la dette explose → l’équipe est sous l’eau… Stop !

Changer le postulat de base et ajouter une nouvelle entrée dans l'équation : formation, mindset, une personne/un expert, …

⇒ Accepter le changement, accepter de changer de façon de faire, accepter de ne pas savoir et continuer d’apprendre car souvent, comme le dit l’effet Dunning-Kruger (aussi appelé “effet de surconfiance"):

"on ne sait pas qu'on ne sait pas"

Si vous ne voulez pas refaire votre système tous les 2 ans, investissez dès le début et en continu.

En conclusion, être rattrapé par la complexité accidentelle n’est pas une fatalité, et heureusement, mais la combattre demande un effort permanent de la part de toute l’équipe. Et soyons réaliste : ne pas avoir de dette est illusoire… mais il faut savoir la résorber au fil de l’eau !