Le DDD, l'arme secrète pour des projets IA plus performants
Quand ton assistant IA ne peut pas lire dans tes pensées
Soyons honnêtes : tu t'es probablement déjà arraché les cheveux avec un assistant IA de codage. Tu demandes une fonctionnalité, et il te sort quelque chose qui fonctionne techniquement mais qui rate complètement l'objectif. Des noms de classes génériques. De la logique dispersée dans des helper classes. Un mépris total des règles métier qui font la valeur de ton application.
Voici la vérité qui fait mal : l'IA n'est pas le problème. Tu l'es.
Pas pour te culpabiliser — pour être pragmatique. Les modèles de langage IA sont exceptionnels pour reconnaître des patterns et générer du code, mais ils sont limités par ce que tu leur donnes. Tu donnes un contexte vague à une IA, tu obtiens du code vague. Des instructions ambiguës ? Un comportement ambigu.
C'est là que le Domain-Driven Design (DDD) entre en jeu, et sincèrement, c'est la meilleure chose arrivée au développement assisté par IA depuis l'autocomplétion.
Ce que le DDD est réellement (sans le blabla académique)
Je sais ce que tu penses : « DDD ? C'est cette méthodologie lourde avec ses 47 patterns et son livre bleu de 800 pages, non ? »
Oui et non.
Le DDD est fondamentalement un pari sur l'endroit où réside la complexité dans un logiciel. La premise : dans la plupart des applications, la partie difficile n'est pas la technologie — c'est de comprendre et de modéliser le domaine. Les règles métier, la terminologie qui a un sens précis ici mais pas là, les cas limites qui n'ont de sens que dans leur contexte.
Donc le DDD dit : place un modèle de ton domaine au centre de ton travail. Exprime ce modèle dans un langage que les développeurs ET les experts métier comprennent. Fais en sorte que le code reflète directement ce modèle.
La partie stratégique couvre la vue d'ensemble : établir un vocabulaire partagé (appelé Langage Ubiquiste) et définir des limites (Bounded Contexts) là où ce langage reste cohérent.
La partie tactique couvre les briques de construction : les entités qui ont une identité, les value objects définis par leurs attributs, les aggregates qui regroupent des objets liés, et les événements métier qui capturent les changements significatifs.
L'anti-pattern à surveiller — et celui-ci piége même les développeurs expérimentés — c'est le « modèle anémique ». C'est quand tes objets ne sont que des sacs de données avec des getters et setters, tandis que toute la vraie logique vit dans des classes service séparées. Le DDD s'y oppose fermement : mets le comportement là où se trouvent les données.
Pourquoi c'est important pour les assistants IA de codage
Voici où ça devient intéressant pour nous en 2024 et au-delà.
Les modèles de langage IA sont essentiellement des moteurs de complétion de patterns dopés aux stéroïdes. Ils prédisent à quoi le code devrait ressembler en fonction de ce qu'ils ont vu dans leurs données d'entraînement. Et voici le problème : ces données sont pleines de patterns CRUD anémiques, de nommage générique et de logique dispersée. C'est le chemin de moindre résistance dans la plupart des bases de code, donc c'est ce que les modèles utilisent par défaut.
Quand tu utilises les principes du DDD, tu provides en gros des garde-fous qui orientent l'IA vers de meilleurs résultats. Chaque artefact DDD que tu crées devient du material de prompt. Chaque décision que tu rends explicite devient une contrainte avec laquelle l'IA peut travailler.
Laisse-moi te montrer les quatre endroits où c'est le plus important :
1. Ton vocabulaire partagé devient le system prompt de l'IA
Imagine : tu construis un système de gestion d'abonnements. Ton équipe s'est mise d'accord sur le fait que « abonnement », « plan » et « entitlement » veulent dire des choses très précises. Un abonnement est une relation active entre un client et un plan. Un plan définit ce qui est disponible. Un entitlement, c'est ce que le client peut réellement utiliser.
Quand tu écris une user story ou une description de fonctionnalité en utilisant ces termes précis, l'IA peut internaliser ce vocabulaire. Demande-lui d'ajouter une fonctionnalité pour « upgrader les abonnements », et elle génèrera du code qui respecte ces distinctions. Elle ne mélangera pas « plan » et « entitlement » parce que tu as été explicite sur leurs rôles séparés.
Ce glossaire que tu maintiens pour intégrer les nouveaux développeurs ? C'est aussi exactement ce dont l'IA a besoin. Même information, double usage.
2. Les Bounded Contexts gardent les sessions IA concentrées
Tu as déjà essayé de faire aider l'IA sur une fonctionnalité qui touche six parties différentes de ton système ? Les résultats sont généralement chaotiques — des changements partiels, des dépendances manquées, une logique qui se contredit entre les modules.
Les bounded contexts résolvent ça naturellement. Chaque context est une zone définie où un modèle et un langage particulier s'appliquent. Quand tu travailles dans le context « Facturation », le terme « compte » peut vouloir dire quelque chose de différent que dans le context « Gestion des Utilisateurs ». C'est OK, tant que les frontières sont claires.
Pour les workflows IA, ça se mape magnifiquement sur des sessions concentrées. « Aujourd'hui on travaille dans le context Order Fulfillment. Voici son vocabulaire et ses règles. Ignore le context Inventory pour l'instant. » C'est comme ça que tu obtiens que le modèle reste sur cible au lieu de s'étaler sur tout ton système.
3. Les modèles riches en comportement protégent tes règles métier
C'est le bénéfice pratique en termes de sécurité qui est souvent négligé.
Quand tu mets les règles métier à l'intérieur des objets qui possèdent les données pertinentes, il y a un seul endroit pour les protéger. Quand tu disperses ces règles dans plusieurs classes service, n'importe quel code généré peut accidentellement les contourner.
Considère une règle de validation de commande : une commande ne peut pas être expédiée si le paiement n'a pas été validé. Si cette règle vit dans Order.Ship(), elle est protégée. N'importe quel code qui essaie d'expédier une commande impayée passe par cette vérification. Mais si la règle vit dans un ShippingService séparé, une IA qui génère du code pourrait joyeusement créer un nouveau ShippingProcessor qui expédie des commandes sans vérifier le statut du paiement.
Les modèles riches en comportement concentrent tes invariants dans des endroits où ils peuvent réellement protéger le système.
4. Les tests deviennent des spécifications exécutables
L'accent mis par le DDD sur les invariants — les règles qui doivent toujours être vraies — se traduit directement en cas de test. « Un abonnement ne peut pas être renouvelé après avoir été annulé. » « Un utilisateur ne peut pas transférer plus de crédits qu'il n'en a. » « Une commande ne peut pas être expédiée vers une adresse incomplète. »
Ce ne sont pas juste de bons tests. C'est une définition de la correction que l'IA peut utiliser. Écris-les en premier, et l'IA a une cible concrète pour coder. Elle peut exécuter les tests et savoir immédiatement si elle est sur la bonne voie. C'est beaucoup plus fiable que d'espérer qu'elle suive des descriptions en prose des règles métier.
Les pièges à éviter**
Je veux être direct avec toi : utiliser le DDD avec l'IA, ce n'est pas de la magie automatique. Les valeurs par défaut jouent contre toi de certaines manières spécifiques.
L'IA default vers du CRUD anémique. Si tu demandes « une classe Customer », tu auras souvent une paire getter/setter publique avec toute la logique exilée vers un service séparé. Tu dois explicitement demander du comportement sur l'objet, des setters privés, et de la logique qui vit avec les données qu'elle protège.
L'IA invente du vocabulaire. Tu dis « order », elle écrit « transaction ». Tu dis « subscription », elle écrit « membership ». Ce ne sont pas des synonymes dans ton domaine, mais l'IA ne le sait pas sauf si tu le lui dis. Un vocabulaire cohérent et explicite dans tes prompts aide, mais aussi mettre ces termes dans les noms de fichiers, les noms de classes et les commentaires où l'IA les pickera naturellement.
L'IA sur-architecte quand elle n'est pas sûre. Quand une IA n'a pas de guidance claire sur le bon niveau de complexité, elle souvent defaults vers des patterns élaborés — des abstract factories, des interfaces excessives, des couches inutiles. Le DDD fournit en fait une heuristique utile ici : utilise les patterns coûteux (aggregates, événements métier, bounded contexts) seulement quand la complexité du domaine les justifie. Pour des domaines plus simples, des classes riches en comportement avec des noms clairs pourraient être tout ce dont tu as besoin.
Le takeaway pratique**
Voici mon évaluation honnête après avoir réfléchi à ce pattern : le DDD n'est plus principalement une méthodologie de codage. C'est une méthodologie de context-engineering pour l'ère de l'IA.
Chaque pratique DDD que tu adoptes rend ton domaine plus explicite, et explicite, c'est exactement ce sur quoi les modèles de langage peuvent agir. Le vocabulaire partagé que tu construis pour ton équipe devient le vocabulaire que l'IA utilise. Les bounded contexts que tu dessines deviennent des unités de travail naturelles pour des sessions IA concentrées. Les modèles riches en comportement que tu crées deviennent des espaces protégés où les règles métier ne peuvent pas être tranquillement contournées.
Tu allais faire ce travail de toute façon, si tu voulais un logiciel maintenable. Maintenant ça rapporte aussi avec les assistants IA.
Les parties « pas chères » du DDD — la clarté du langage et la concentration du comportement — s'appliquent partout. Les parties « coûteuses » — les patterns tactiques complets, l'event sourcing élaboré — s'appliquent seulement là où la complexité du domaine le justifie sincèrement.
Commence par les parties pas chères. Rends le vocabulaire explicite. Mets le comportement avec les données. Garde les frontières claires. Ensuite laisse l'IA t'aider à implémenter le reste.
Ton futur toi, en train de débugger du code à 2h du matin, t'en sera reconnaissant. Et l'IA qui parvient réellement à aider au lieu de gêner aussi.