Le PIRE ennemi des développeurs (et comment le combattre).


Le pire ennemi des développeurs

Si vous suivez mon blog, vous savez que j’aime parler de bonnes pratiques. J’aime vraiment BEAUCOUP ça.

Qu’il s’agisse de lisibilité du code (nommage), de documentation (commentaires) ou de concept architecturaux (SOLID et patrons de conception), c’est une vraie obsession.

Mais pourquoi en avoir fait une affaire aussi personnelle ?

En fait, chaque article traite son problème de long en large, mais en plus, il apporte son grain de sable à la résolution d’un problème que je considère comme étant un, si ce n’est LE plus important dans notre milieu : la dette technique.

Je l’ai souvent évoqué (14/31 articles pour être précis), mais pourtant, je ne l’ai jamais réellement défini.

Il s’agit d’une métrique permettant de mesurer la quantité de friction dans la maintenance corrective (résolution de bugs) et évolutive (ajout de fonctionnalités) d’une application.

Autrement dit, plus vous en avez, plus la maintenance sera fastidieuse.

C’est une analogie évidente à la dette financière avec laquelle elle partage plusieurs caractéristiques :

  • Emprunt : le sacrifice des bonnes pratiques pour un développement plus rapide.
  • Intérêts : la friction dans la maintenance qui est la conséquence de l’emprunt.
  • Remboursement : le réusinage du code pour remettre les bonnes pratiques au gout du jour, qui va compenser tout le temps que vous avez emprunté et éliminer les intérêts.
Image de freepik.com.

En soi, la dette technique n’est pas toujours une mauvaise chose. Si vous avez besoin de sortir un produit le plus vite possible (par exemple, un MVP), emprunter peut vous donner le boost de vitesse qu’il vous faut.

Le hic, c’est que la dette technique n’est JAMAIS rentable, et le retour de bâton est inévitable.

Comme pour l’achat d’une voiture, emprunter vous permettra de l’avoir plus vite, mais financièrement, vous êtes toujours perdant, car vous allez devoir la rembourser en plus de ses intérêts.

Et plus vous attendrez, plus les intérêts vont monter. Ça commence à 100%, puis 110%, 130%, 160%… Et rapidement, vous vous retrouvez à devoir rembourser le triple.

Passé un certain seuil, son impact sur le projet est absolument catastrophique, car elle sabote :

  • Le délai de livraison : la maintenance est si difficile que les développeurs n’arrivent plus à tenir le rythme.
  • La qualité du produit : les développeurs vont bâcler le travail pour respecter les délais, ce qui risque d’introduire beaucoup de bugs et encore plus de dette technique.
  • Le moral des développeurs : ça va complètement anéantir leur motivation, et la productivité suivra. Dans le pire des cas, les meilleurs vont ragequit, et seuls les moins compétents resteront.

Et quand ça finit par arriver chez le client (souvent sous la forme d’une démo horriblement embarrassante), celui-ci refuse le produit, dresse sa meilleure croix sur le contrat, et votre entreprise met la clef sous la porte.

Image de freepik.com.
T’y vas un peu fort là, non ?

Et pourtant, je n’invente rien.

En 2002, la NIST estimait le coût des bugs logiciels à 60 milliards de dollars. Ajoutez les heures de développements perdues, le coût des projets abandonnés, etc. On doit bien-être au double.

Imaginez une seconde le même calcul en 2020. Honnêtement, si l’on me disait 500 milliards, je ne serais même pas surpris.

Et les séquelles sur le moral des développeurs ne sont pas non plus à négliger.

Cette frustration quand on travaille sur du code immonde, cette humiliation devant les utilisateurs quand on leur montre l’horreur qu’on est en train de produire, ce sentiment d’être en train de perdre son temps, de travailler sur les mauvaises choses, d’être peu productif, le syndrome de l’imposteur… Vous connaissez ? Parce que moi oui.

La dette technique est aussi malsaine économiquement que psychologiquement, et c’est pour ça que je prends l’affaire aussi au sérieux.

Ça va, vous vous sentez bien ?


Le bon côté de la matrice

Voici une autre mauvaise nouvelle : la dette technique n’est pas toujours évitable. À vrai dire, elle est même parfois nécessaire.

Martin Fowler l’a bien représenté sur sa matrice des causes de la dette technique.

On distingue deux catégories :

  • L’erreur humaine : un mauvais design qui laisse des séquelles sur le projet.
  • Le profit des avantages à court terme : typiquement, le coup de pression pour que l’application soit prête avant la démo.

En soi, ces raisons se comprennent. On fait tous des erreurs (pas trop j’espère 😜), et l’on ne travaille pas toujours dans des conditions optimales.

Mais la seconde dimension du tableau est intéressante, car elle distingue les causes recevables de celles réellement inadmissibles.

Typiquement, un développeur qui n’avait pas prévu un changement dans son architecture, c’est chiant, mais ça arrive même aux meilleurs.

Par contre, un développeur qui bâcle une architecture ou qui ne connait pas les concepts de base, c’est beaucoup plus grave.

Quelques phrases clefs pour situer vos collaborateurs sur la matrice.

Le but de cet article (et de mon blog) est de vous donner les armes nécessaires pour comprendre, gérer, prévenir, voir éviter la dette technique pour que vous soyez toujours à droite de cette matrice.

Le but est d’avoir tous les risques sous contrôles, et permettre au projet de voir la douce lumière de la victoire.


Analyser sa dette technique

Comment l’évaluer ?

C’est une bonne pratique de prendre régulièrement la température de votre codebase. Non pas pour rédiger un superbe rapport que votre manageur ne lira pas, mais pour savoir s’il est temps de la réusiner une bonne fois pour toutes.

Il existe des tas d’outils et de méthodologies, tels que SQALE… Mais honnêtement, pour une analyse non officielle, vous n’en aurez pas besoin.

Étant donné que vous avez les mains dans le cambouis toute la journée, vous devriez être capable de faire une analyse à la grosse relativement aisément.

Voici mon framework :

  1. Estimez honnêtement le temps que ça vous prendrait d’implémenter une nouvelle exigence dans un système optimal (sans vous prendre pour Apollon non plus 😂).
  2. Comparez avec le temps que ça vous a réellement pris.

À moins que vous ayez VRAIMENT foiré votre estimation, le temps réel devrait toujours être supérieur au temps attendu. C’est normal, car la chose à retenir est le décalage entre les deux.

Plus celui-ci est grand, plus votre projet est rongé par la dette technique, et plus un remboursement s’impose.


Quel taux faut-il viser ?

Le zéro-dette technique n’existe pas, c’est mathématiquement impossible. Mais ce n’est pas non plus un idéal vers lequel il faut tendre.

Le taux parfait est relatif aux différentes ressources de votre projet.

C’est ce que j’appelle le taux de base. Il faut le trouver, et s’y tenir, car :

  • Si vous êtes au-dessus, vous allez souffrir de la friction dans la maintenance.
  • Si vous êtes en dessous, vous allez passer trop de temps à créer et faire respecter une architecture inutilement complexe par rapport au produit.

Il faut aussi définir un plafond à ne jamais dépasser pour éviter que les choses deviennent hors de contrôle. S’il est atteint, on arrête tout et l’on rembourse.

En général, elle sera toujours au-dessus du taux de base, vu qu’il plus facile de tout péter que de faire du trop bon travail.
Eh ! Pas si vite, comment je fais pour calculer ces taux-là ?

Pour le plafond, c’est très simple : c’est la quantité de dette technique à laquelle vous n’êtes plus en mesure de livrer un produit sans bug à temps, contrôles qualité inclus.

Autrement dit, s’il est atteint et que vous vous entêtez, le projet s’écroule. Donc gardez-vous un peu de marge 😊

Pour le taux de base, c’est plus compliqué, car il faut prendre en compte les différentes ressources du projet. Voici quelques facteurs qui vont le tirer vers le bas :

  • Longue durée du projet : jusqu’à l’arrêt du développement.
  • Longue durée étendue du projet : jusqu’à l’arrêt de la maintenance et l’obsolescence de l’application.
  • Manque de ressources matérielles : les ordinateurs, logiciels de développement, bibliothèques, outils de CD/CI
  • Beaucoup de développeurs dans l’équipe : ça signifie une coordination plus difficile, d’où l’intérêt d’avoir une architecture très solide.
  • Peu d’expérience chez les développeurs : les juniors étant bien moins sensibilisés sur le sujet, ils représentent un risque beaucoup plus grand, d’où l’intérêt de toujours avoir quelqu’un de très expérimenté pour garder la codebase sur les rails.
Image de freepik.com.

J’en oublie surement, mais ce n’est pas non plus une science exacte, une estimation à la grosse suffit. L’important est de :

  1. Fixer un taux de base.
  2. Designer une architecture qui permettra de respecter ce taux de base (plus celui-ci est bas, et plus l’architecture sera complexe).
  3. Travailler sur le produit en respectant les conseils de la prochaine partie.

Conseils pratiques

Le taux de base est défini, l’architecture est faite et le projet est lancé, félicitations ! Il ne reste plus qu’à développer le produit en prenant soin de garder la dette technique entre les deux taux, de préférence le plus bas possible.

Ok patron, comment on fait ?

Rien de plus simple, j’ai un blog entier dédié à ça 😄

Plus sérieusement, le sujet est tellement complexe qu’en mille livres on n’aurait pas fait le tour. Donc ici, je vais uniquement vous donner les grandes lignes de ce qui me semble le plus important.

Mais si le sujet vous intéresse, un p’tit partage pour me montrer votre enthousiasme, ça ne fait de mal à personne 😏


À titre individuel

1. Apprendre et appliquer les bonnes pratiques de base.

Nommage, commentaires, fonctions courtes, formatage, nombre de paramètres… Toutes ces bricoles qui permettent de rendre le code lisible même par votre grand-mère.

Ces bonnes pratiques ne doivent JAMAIS être négligées, même sous pression, car dès qu’il commence à y avoir quelques erreurs, c’est la porte ouverte au syndrome de la vitre cassée.

Donc, apprenez-les toutes et appliquez-les jusqu’à ce que ça devienne un réflexe. C’est frustrant au début, mais une fois que vous maitrisez ça, vous allez écrire du code si beau qu’il en ferait rougir De Musset.


2. Passer plus de temps en phase d’architecture.

Je sais à quel point c’est tentant de se jeter immédiatement sur le code, mais sérieusement, ne le faites pas.

Prenez le temps qu’il faut pour désigner une codebase qui soit à la fois robuste et flexible, car une fois ça fait, l’implémentation et la maintenance sera un jeu d’enfant.

Rien ne sert de courir, il faut partir à point.
Jean de La Fontaine, Le lièvre et la tortue.

3. Designer une codebase pour le changement.

Il y a plein de paramètres à prendre en compte pour designer une codebase : les performances, la simplicité, la sécurité… Mais pour lutter contre la dette technique, la plus importante est la flexibilité.

Il faut laisser des portes ouvertes à l’évolution PARTOUT, de manière à ce que chaque nouvelle exigence soit ridiculement simple à implémenter.

Si vous ne savez pas par où commencer, je vous renvoie vers mes séries sur les principes SOLID et les patrons de conception.

Image de freepik.com.

4. Faire des tests automatiques.

Outre le fait de valider votre application, les tests automatiques sont extrêmement efficaces pour éviter les régressions, car dès qu’un module change, vous n’avez qu’à lancer vos tests pour vous assurer que ça n’a rien cassé ailleurs.

Ils permettent de livrer plus vite et avec moins de bugs, mais aussi de faciliter le remboursement de la dette technique, car les développeurs pourront réusiner le code sans avoir peur de tout péter.


5. Faire de l’intégration et du déploiement continu.

Qu’il s’agisse d’un beau pipeline sur GitLab ou d’un vieux script PowerShell, peu importe tant que ce qui est chiant et manuel devient facile et automatique.

Non seulement vous gagnez du temps, mais en plus, vous limitez énormément les erreurs humaines qui sont très fréquentes sur ce genre de tâches : push d’un code foireux sur la branche principale, mise en production ratée, et j’en passe.


6. Rembourser le plus rapidement possible.

Plus vous attendrez et plus vous accumulerez des intérêts, donc autant rembourser le plus vite possible.

Dès que vous repérez une source de dette technique, même minime (erreurs de design, module mal nommé…), intervenez immédiatement, ne la laissez surtout pas pourrir !

Laisse toujours le campement (module) plus propre que tu ne l’as trouvé.
Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship.

7. Être bavard avec son client.

Imaginez la manière dont le programme pourrait évoluer, c’est cool. Savoir, c’est encore mieux. Et bien souvent, votre utilisateur final sait, mais ne vous l’a pas dit.

Une communication excellente avec lui est primordiale pour élucider tous les mystères autour du programme et empêcher les designs douteux : écoute active, hexamètre de Quintilien, cinq pourquoi, et surtout, une bonne dose de patience. Bref, soyez un télépathe.

Image de freepik.com.

8. Utiliser des outils d’analyse de code source.

Outils de réusinage, couverture des tests, générateur de documentation, etc. Tout est bon à prendre. Peu importe votre environnement, vous devriez trouver votre bonheur.


À titre collectif

9. Documenter votre codebase.

Je ne parle pas de simples commentaires, mais bien d’un module d’emploi complet, avec une explication de l’architecture, une documentation d’API, etc.

L’intérêt n’est pas pour vous, puisque vous connaissez déjà le système sur le bout des doigts, mais pour les nouveaux arrivants dans les projets. Ces personnes sont dangereuses, car elles ne connaissent rien à la codebase, et risquent de la pourrir de mauvaises pratiques.

En leur fournissant une documentation de qualité (et en les forçant à l’étudier), vous les intégrez encore plus rapidement dans le projet tout en évitant une catastrophe.


10. Former et sensibiliser les membres de l’équipe.

Aucune technologie ne viendra compenser une équipe qui manque de compétences.

Sensibiliser et former ses collègues sur les bonnes pratiques est un des meilleurs investissements que vous pouvez faire sur le long terme.

Conseillez-leur des livres, des articles (coucou 🤗), coachez-les, faites-leur suivre une formation aux frais de l’entreprise, mais ne les confortez surtout pas dans leur bulle, en particulier s’ils livrent du spaghetti code.


11. Faire des revues de code.

Ça signifie relire le code d’un autre développeur pour détecter des éventuels bugs et mauvaises pratiques. Elles peuvent se faire indirectement via une pull request, ou de manière plus conversationnelle dans une réunion.

Non seulement elles permettent de contrôler la qualité du code, mais surtout, elles sont un excellent moyen de coacher vos collègues sur les bonnes pratiques.

C’est généralement dans ces moments-là qu’un développeur tire ses meilleures leçons qui le suivront toute sa vie. C’est beau 🤤


12. Surveillez l’atmosphère de l’équipe.

Le mauvais code et les piètres performances d’une personne ne sont pas qu’une affaire de manque de compétences, et souvent, elles révèlent un problème bien plus profond que ça : perte de motivation, inconfort au sein de l’équipe, problèmes personnels, toxicité (fainéantise, hostilité), etc.

Prendre conscience de ces problèmes et apporter des solutions est essentiel, en particulier si vous êtes proche des personnes en question. Pour limiter la dette technique, certes, mais surtout pour préserver la santé mentale de tout le monde.

À l’heure où j’écris ces lignes, le développement informatique est toujours une affaire humaine, avec des problèmes d’humains. Et franchement, ~même si c’est parfois chiant~, j’espère que ça ne changera pas de sitôt !

Image de freepik.com.

Voilà pour cet article sur la dette technique. Évidemment, je n’ai fait qu’effleurer, frôler, chatouiller la surface de ce sujet, et chaque point de ma liste mérite plusieurs articles à eux seuls.

Ne vous inquiétez pas, un jour ou l’autre, ils arriveront. Donc si le sujet vous intéresse vraiment, vous savez qui ajouter dans votre flux RSS 😊

Merci d’avoir lu cet article jusqu’au bout, c’est surement un des plus importants sur ce blog, donc j’espère qu’il vous a plu autant que j’ai eu d’intérêt à le faire !

Si c’est le cas, faites-en profiter votre entourage en le partageant 💙 Et suivez-moi sur Twitter @ITExpertFr où je raconte et partage un tas de choses (presque) aussi intéressantes.

Et pour les déterminés qui veulent affronter la dette technique encore plus efficacement, je vous recommande de cliquer sur le logo tout en haut à gauche de cette page… Bonne lecture 😉

Quant à moi, je vous laisse, je vais aller miner un peu de Bitcoins pour rembourser l’emprunt de ma nouvelle Porsche.

À bientôt pour un nouvel article sur le blog des développeurs ultra-efficaces. Tchao !