Environnement

“Make it work, make it right, make it fast.”
– Ken Beck
Écrire une nouvelle application, c’est grisant. Tout est propre, rapide, fluide. Vous êtes un artiste, un architecte du 21e siècle, libre de vos choix technologiques. Le code est peut-être bancal, mais il fonctionne. Pour l’instant.
Parce qu’en réalité, ce que vous venez de faire, c’est signer un contrat à durée indéterminée avec le chaos. Ce « proof of concept » qui tenait par miracle est désormais en production. Et chaque ligne de code que vous avez écrite vous envoie un rappel sournois : « À très vite pour une session de débogage nocturne. »
La vraie difficulté commence quand on vous demande « juste une petite modif » — traduisez : casser tout l’équilibre précaire du projet. Ou quand une dépendance décide de disparaître du jour au lendemain, emportant avec elle votre API, votre backend, et votre foi en l’humanité. Car une application qui ne change pas, meurt. Et celle qui change ? Elle vous tue à petit feu. Il n’y a pas d’issue heureuse.
C’est cette maintenance qui est difficile : selon certaines études académiques et industrielles (Krupp 2021), 60 à 80% du coût associé à n’importe quelle ligne de code correspond à de la maintenance de la ligne initialement écrite. Pas son développement. Sa maintenance. Cette activité passionnante qui consiste à réparer vos propres erreurs, à contourner celles des autres, et à mettre à jour des bibliothèques qui n’existent plus.
Appliquer les principes suivants, c’est surtout une manière polie de se préparer à moins souffrir plus tard. Le but est simple : écrire aujourd’hui du code que vous ne haïrez pas demain, ni vous, ni votre remplaçant(e), ni votre vous du futur à 3h du matin.
Pour paraphraser une partie de l’introduction du livre Clean Architecture (Martin 2018)
“Getting software right is hard : it takes knowledge and skills that most young programmers don’t take the time to develop. It requires a level of discipline and dedication that most programmers never dreamed they’d need. Mostly, it takes a passion for the craft and the desire to be a professional.”
– Robert C. Martin
Le développement d’un logiciel nécessite une rigueur d’exécution et des connaissances précises dans des domaines extrêmement variés. Il nécessite également des intentions, des prises de décisions et énormément d’attention. Indépendamment de l’architecture que vous aurez choisie et des technologies que vous aurez patiemment évaluées, une architecture et une solution peuvent être cassées en un instant, en même temps que tout ce que vous aurez construit, dès que vous en aurez détourné le regard.
L’objectif de cette partie consistera à placer les barrières et les gardes-fous architecturaux, afin de péréniser au maximum les acquis, se garder le maximum d’options et n’avancer que lorsque nous serons sûrs de le faire sur des bases stables.
“La perfection est atteinte, non pas lorsqu’il n’y a plus rien à ajouter, mais lorsqu’il n’y a plus rien à retirer.”
– Antoine de Saint-Exupéry
Il est impossible d’imaginer ou de se projeter dans tous les éléments qui pourraient devoir être modifiés après que votre développement ait été livrée. En ayant connaissance de toutes les choses qui pourraient être modifiées par la suite, l’idée est de pousser le développement jusqu’au point où une décision pourrait devoir être faite. A ce stade, l’architecture nécessitera des modifications, mais aura déjà intégré le fait que cette possibilité existe.
Il est tout simplement impossible de prédire l’avenir d’une application : les demandes des utilisateurs, l’évolution des langages, les changements dans les bibliothèques tierces ou même le support des navigateurs sont autant de variables hors de votre contrôle. Avec un peu d’expérience (ou une bonne dose d’anxiété anticipée), on apprend que tenter de tout prévoir est non seulement vain, mais contre-productif. C’est ici que le principe bien connu du YAGNI — You Ain’t Gonna Need It — prend tout son sens : tenter de développer aujourd’hui toutes les fonctionnalités que vous pourriez, peut-être, avoir besoin un jour, reviendrait à alourdir inutilement le code, à complexifier les déploiements, à embrouiller les utilisateurs, et à saper la maintenabilité de votre propre travail.
Inutile donc d’écrire du code “en prévision de” : l’important est plutôt d’amener votre architecture au point où, si un changement s’avère nécessaire, il pourra être intégré sans tout casser. Cela ne signifie pas anticiper tous les cas, ni ignorer les signaux faibles : simplement reconnaître que des modifications viendront, et s’y préparer sans sur-ingénierie. C’est une posture de compromis : on ne code pas “au cas où”, mais on garde les portes entrouvertes.
“Aujourd’hui, n’importe qui peut générer du code en quelques secondes. Mais personne ne vous prévient que ce code, demain, vous haïra.”
Key takeaways :
- Chapitre 1 : Eléments d’architecture.
- Chapitre 2 : Fiabilité, évolutivité, maintenabilité.
- Chapitre 3 : Tester, c’est douter.
- Chapitre 4 : Contraintes non fonctionnelles