L'art délicat de l'adoption du craft
ou comment accompagner la montée en compétence d'une équipe logicielle.
On échoue souvent à convaincre de la pertinence d'une architecture logicielle. D'abord parce que rendre concrets des principes abstraits est un exercice difficile. Mais surtout parce qu'on la vend mal.
La cause profonde est presque toujours la même : on demande à une équipe en place de fournir un effort d'adoption supplémentaire pour un bénéfice qui, de son point de vue, est au mieux hypothétique. Alors que l'échéance calendaire, elle, est très tangible. Le calcul est vite fait.
J'ai passé assez de temps à défendre la clean architecture, le DDD et les tests sans mocks pour savoir que les arguments théoriques ne convainquent personne. Donc si vous vous préparez à aller au combat pour défendre ces architectures auprès de votre hiérarchie, de votre collègue adepte du CRUD ou de votre mémé, voici quelques tuyaux qui pourront vous être utiles.
L'adoption vient de la résolution d'un pain point
Personne n'adopte une architecture pour sa beauté. On l'adopte parce qu'elle résout une douleur. Et parmi ces douleurs, certaines reviennent tout le temps :
- une vélocité qui chute release après release
- des tests trop compliqués à écrire, ou trop lents à s'exécuter
- un taux de défaut trop important
- un logiciel globalement difficile à faire évoluer
Encore faut-il que l'équipe en place ne soit pas dans le déni. Tel Amonbofis dans Astérix et Cléopâtre, elle peut être victime du syndrome "je vois pas pourquoi on ferait autrement, on a toujours fait comme ça". Là vous avez un autre genre de problème, qui commence par faire ouvrir les yeux avant de parler d'architecture.
Prenons le cas type : un développeur expérimenté, compétent, qui ne jure que par le MVC brut et qui a rangé la clean archi dans la case "sur-ingénierie académique". Attaquer frontalement avec Evans ou Uncle Bob renforce sa position. Il a déjà entendu "séparation des responsabilités" et "testabilité", et il a déjà décidé que ça ne valait pas le coût.
Au passage, le name dropping est la technique la plus contre-productive que vous puissiez employer. Non seulement ça ne convainc personne, mais ça braque votre interlocuteur s'il n'a pas les refs. À bannir définitivement.
Le seul angle qui fonctionne, c'est la douleur qu'il a déjà vécue.
Levier 1 : la question qui ouvre
Tout dev MVC avec quelques années d'expérience a maintenu un controller de 800 lignes, ou un service fourre-tout où la règle métier "un client premium a droit à trois relances" est dupliquée à quatre endroits. Si vous trouvez un de ces contrôleurs dans le code, il suffit généralement à expliquer la majorité des douleurs listées plus haut.
La bonne question pour impulser un changement n'est donc pas "connais-tu l'architecture hexagonale ?". C'est : "la dernière fois que tu as dû changer cette règle, combien de fichiers as-tu touchés ? Combien de régressions ?"
On part de là, et on propose des solutions. Sans nom compliqué, sans verbiage. Juste des solutions : "et si on modélisait le comportement de cette entité dans une classe séparée, qui n'aurait pour responsabilité que ce comportement ? On verra après pour stocker ça en base."
Levier 2 : la démo qui prend trois minutes
Extension directe du premier levier : le pair programming. Montrez, sur son code, comment du code métier bien architecturé se teste facilement et en isolation. Ça prend trois minutes, effet waouh garanti.
En MVC brut, la logique est enchevêtrée avec le framework et la persistance. Avec un domaine isolé, le test est un test unitaire pur qui tourne en millisecondes. C'est un argument de vélocité, pas d'esthétique. Et les développeurs pragmatiques sont très sensibles à la vélocité.
Levier 3 : le flou crudien
Dans une application orientée ressources, où met-on un processus qui engage plusieurs ressources ? Exemple : dans un gestionnaire de bibliothèque, dans quel service met-on le traitement "un utilisateur emprunte un livre" ? Dans le service User, dans le service Stock ou dans le service Livre ?
La question a l'air débile posée comme ça. Mais prenez trois développeurs et vous aurez trois réponses différentes. Ce flou est endémique à la logique crudienne : le métier n'a nulle part où habiter, alors chacun le range où il peut. Dans une application organisée par cas d'usage, vous aurez un use case borrow_book, et la question ne se pose plus.
Levier 4 : commencer petit
C'est peut-être le plus important. Ne vendez pas le package complet. Clean archi + DDD + CQRS + Event Sourcing présentés comme un bloc, ça fait peur. À juste titre.
Une seule proposition suffit pour commencer. Sortir la logique métier des contrôleurs web vers des objets du domaine sans dépendance au framework, par exemple : c'est déjà un grand pas, et on gagne de la testabilité immédiate. Ou bien encapsuler les effets de bord derrière des abstractions (ports et adapters).
Le reste viendra quand les besoins le justifieront.
Et si ça ne prend pas
Un plan de secours et un principe de base peuvent aider.
D'abord, l'architecture mixte. Si l'équipe ne veut pas basculer entièrement, proposez de découper le code en bounded contexts : les contextes simples restent en CRUD, les contextes à forte logique métier adoptent d'autres principes architecturaux. Personne ne perd la face, et vous obtenez un terrain de démonstration grandeur nature.
Ensuite, accordez-vous, ainsi qu'à vos équipes, le droit de vous planter. Le devoir, même. Les règles canoniques sont faites pour être adaptées. Ce qui compte, c'est le gain qu'on en retire, pas la satisfaction d'une réalisation by-the-book. Si votre implémentation n'est pas exacte du premier coup, ce n'est pas grave, du moment qu'elle apporte une solution concrète à un problème identifié.
Parce qu'au fond c'est ça, la montée en compétence d'une équipe : pas une conversion à une doctrine, mais une série de problèmes concrets résolus, un par un, jusqu'au jour où la bonne pratique devient simplement le chemin le plus court.
Commentaires ()