J'ai récemment vu passer une discussion sur le clean code, le TDD... les bonnes pratiques en somme. Un développeur y racontait une expérience assez courante que je vais résumer ici.
Un point de vue pragmatique
On lui avait confié une application où toute la logique était dans le fichier App.js
, de plusieurs milliers de lignes. Une catastrophe à maintenir, ou même seulement lire et comprendre.
Cependant, cette version boiteuse avait permis de lever des millions d'euros pour financer le projet.
Dans les mois qui ont suivi, avec cet argent dans les caisses, une équipe de dix développeurs a retapé tout le code pour avoir quelque chose qui tienne debout et qu'on puisse maintenir.
Suite à cela, le développeur conclut que le résultat compte plus que le code.
Il y a dans ce propos une réalité à ne jamais oublier : optimiser à outrance un projet dont on ne connaît pas l'avenir est un énorme risque à prendre. Si le projet ne marche pas, le temps passé dessus aura été inutile.
Dans son cas, ça s'est bien terminé et...
Ma réalité à moi (et sans doute la vôtre)
J'ai eu une expérience similaire (sans les millions de financement) : notre équipe avait reçu une sorte de test pour une application, et si le travail était satisfaisant, on serait pris pour la suite du projet.
Des composants avaient déjà été posés, mais il fallait appliquer le nouveau design. Le délai étant court (une semaine), j'avais pour aide un intégrateur CSS, et je devais m'occuper de la partie fonctionnelle avec ReactJS.
Très vite, nous avons été bloqués à cause de bugs incompréhensibles empêchant l'affichage de certains composants.
Bien que cette partie ne nous concerne pas (notre mission se limitant à l'intégration), ça nous empêchait de montrer notre travail au client. J'ai donc regardé ce qui coinçait.
Le cauchemar
Je réalise stupéfait que la logique de toutes les pages se trouvait dans le composant racine App !
Des milliers de lignes de code dans un seul fichier !
Les données étaient transmises de niveau en niveau jusqu'aux composants des pages par du prop drilling*, et les actions des utilisateurs étaient remontées de de façon similaire jusqu'au composant racine de l'application.
En gros, chaque composant de l'application remontait tous les composants parents pour une opération, puis la réponse redescendait ces mêmes composants !
*Le prop drilling dans React consiste à transmettre des données de composant en composant en leur faisant traverser tous les composants intermédiaires, même si ces derniers n'utilisent pas ces données.
...
... Faut pas le faire, hein !
C'est quelque chose qui aurait pu être évité en faisant appel à un état global (Redux, Context ou autre).
Mais ici, un état global n'était même pas nécessaire. Ce qui se passait, c'est que les pages faisaient appel à des fonctions qui leur étaient propres en terme de logique, mais qui se trouvaient à la racine de l'application.
Il suffisait juste de mettre la logique des pages...
... dans les pages !
Décision et conséquences
Le truc, c'est que déjà à l'époque, j'étais développeur fullstack, et non simple intégrateur, donc je décide d'enfreindre les instructions et de régler les bugs moi-même, mais sans toucher à la structure (tout reste dans App.js).
Le tout avec l'approbation de mon chef qui voyait là l'occasion de mettre en avance les compétences de l'équipe.
Je me souviens encore de la conversation téléphonique avec le développeur à l'origine du code, intrigué (plus que fâché) de savoir pourquoi on avait touché à la partie logique.
Quelques mois plus tard, le client est revenu vers nous. L'autre développeur avait été remercié. J'ai cru comprendre qu'il était développeur backend, mais ne maîtrisant pas ReactJS (et ses bonnes pratiques), il était un peu perdu.
J'en veux pour preuve le commentaire présent dans le fichier App.js (j'avais pris la photo à l'époque)...
Il savait qu'il avait produit un code impossible à maintenir. Mais il n'est jamais repassé dessus. Oubli ? Contraintes de temps ?
Mais à quel prix ?
Quand le client nous a transmis le projet, il nous a demandé de refaire toute l'appli, backend et frontend (le backend était géré par une autre équipe).
Résultat ? des mois de perdus pour le client :
1 à 3 mois à monter une version foireuse avec un code qui a fini à la poubelle
3 mois à essayer de faire quelque chose avec avant de se rendre compte que c'était voué à l'échec
4 employés (au moins) payés sur cette version à jeter : le premier développeur, le designer, l'intégrateur CSS et votre serviteur.
Plusieurs mois ensuite à tout refaire de zéro (maquette, intégration, backend, etc.)
Conclusion
Donc non, la réalité du code pourri, c'est surtout de gros retards, la multiplication des frais, des employés lassés de refaire le même projet (qui finissent parfois par s'en aller), et des clients qui doutent de leurs prestataires.
Moralité : allez vite, mais bien.
Pas besoin de tout optimiser dès le départ, mais une bonne structure permet de ne pas avoir à tout recommencer de zéro...
Ce message s'adresse également aux clients : à vouloir aller trop vite, vous risquez d'y perdre très gros.