Domain-Driven Design : aligner code et réalité métier

Le Domain-Driven Design (DDD) est une approche de conception logicielle qui place la réalité métier au centre de toutes les décisions techniques. Souvent réduit à une collection de patterns ésotériques réservés aux architectes chevronnés, DDD est avant tout une discipline de communication — un pont entre deux mondes qui se comprennent rarement : celui des experts métier et celui des développeurs. C'est cette friction permanente, plus que la complexité technique elle-même, qui tue la plupart des projets logiciels sur le long terme.
Le vrai problème que DDD résout
Dans la plupart des organisations, le fossé entre le vocabulaire des experts métier et le code produit par les développeurs s'élargit inexorablement avec le temps. Une « commande » pour l'équipe commerciale désigne une intention d'achat assortie de conditions négociées, de délais et de responsabilités contractuelles. Pour le développeur, un Order dans le modèle de données est souvent une table relationnelle avec quelques clés étrangères et un statut stocké en base. Ces deux représentations ne parlent pas de la même chose — et pourtant, elles sont censées modéliser la même réalité.
Cette désynchronisation n'est pas anecdotique. Elle est la première source de bugs, de features mal comprises, de spécifications contradictoires et de réunions interminables où chacun croit parler de la même chose alors que personne n'entend le même mot. DDD attaque ce problème à la racine, en imposant que le code ne soit pas une traduction du métier, mais son expression directe.
Le résultat attendu est contre-intuitif pour beaucoup d'équipes habituées à penser "infrastructure first" : le code doit pouvoir être lu par quelqu'un qui connaît le métier, même s'il ne connaît pas les détails d'implémentation. Si un product manager peut suivre la logique d'un service TraitementCommande sans avoir besoin d'un développeur pour déchiffrer les abstractions, c'est que l'alignement est réussi.
Les concepts fondamentaux, sans les sur-vendre
L'Ubiquitous Language
C'est le point de départ obligatoire — et souvent le plus négligé. Il s'agit d'un vocabulaire commun, défini conjointement entre métier et technique, utilisé de manière cohérente dans le code, les réunions, les tickets Jira, la documentation et les emails. Pas question d'avoir Customer dans le code quand tout le monde dit "client abonné" en réunion, et "prospect qualifié" dans les specs marketing. Chaque terme ambigu est une bombe à retardement.
Concrètement, cela signifie maintenir un glossaire vivant, challengé régulièrement, et s'assurer que les développeurs utilisent les mêmes mots que les product managers dans leurs noms de classes et de méthodes. C'est un effort de discipline continu, pas un workshop ponctuel.
Les Bounded Contexts
Ils résolvent un problème différent : le fait qu'un même mot peut légitimement avoir des significations différentes selon le contexte dans lequel on l'utilise. Un "produit" dans le catalogue a des attributs de présentation, des descriptions marketing, des photos. Un "produit" dans la gestion des stocks a un emplacement, une quantité disponible, un seuil de réapprovisionnement. Vouloir forcer les deux dans le même modèle produit inévitablement un objet générique qui sert mal les deux contextes.
La solution DDD est d'assumer ces frontières explicitement : le Bounded Context "Catalogue Produits" a son propre modèle, ses propres règles, sa propre équipe si possible. Le Bounded Context "Gestion des Stocks" idem. Ils peuvent communiquer — via des événements, des APIs, des adaptateurs — mais ils ne partagent pas leur modèle interne. Cette séparation nette est la condition de l'évolutivité indépendante.
Les Entités
Ce sont des objets avec une identité unique qui persiste dans le temps, indépendamment de leurs attributs. Un client reste le même client même si son adresse change, son email change, son nom change. Ce qui l'identifie c'est son ID, pas ses propriétés. Ce principe, simple en apparence, a des implications profondes sur la manière de modéliser les changements d'état et la traçabilité.
Les Value Objects
Ce sont l'inverse : des objets définis entièrement par leurs attributs, immuables, sans identité propre. Une adresse postale, un montant en devise, une plage de dates — si deux instances ont les mêmes attributs, elles sont interchangeables. L'immuabilité est clé : on ne modifie pas un Value Object, on le remplace. Cela élimine toute une classe de bugs liés aux effets de bord et aux mutations inattendues.
Les Agrégats
Ils regroupent plusieurs entités et Value Objects en une unité transactionnelle cohérente. La Racine d'Agrégat est le seul point d'entrée : rien ne modifie un objet interne de l'agrégat en contournant la racine. Cela garantit que les invariants métier sont toujours respectés. Une commande avec ses lignes de commande est un agrégat classique : on ne modifie pas une ligne directement, on passe toujours par la commande, qui peut valider les règles métier (stock disponible, montant minimum, cohérence des quantités).
Les Domain Events
Ils signalent qu'un fait métier significatif s'est produit et ne peut pas être défait. CommandePassée, PaiementReçu, StockEpuisé — ces événements permettent de découpler les réactions dans le système. Quand une commande est passée, plusieurs choses doivent se produire : notifier l'entrepôt, envoyer un email de confirmation, mettre à jour les stats en temps réel. Avec les Domain Events, chaque réaction est indépendante, ajoutée ou retirée sans modifier le cœur du domaine.
Comment l'implémenter sans tout casser
L'erreur classique est de vouloir adopter DDD en intégralité dès le premier sprint, sur un projet existant, en mode big bang. C'est la garantie d'un échec coûteux et d'une équipe qui rejette l'approche pour une décennie.
L'approche pragmatique : commencer par établir un Ubiquitous Language documenté sous forme de glossaire métier collaboratif. Deux jours de travail suffisent pour couvrir 80 % du vocabulaire critique. Identifier ensuite les Bounded Contexts principaux — en général trois à cinq sur un SaaS de taille moyenne — et cartographier comment ils interagissent. Les patterns tactiques (Entités, Agrégats, Domain Events) sont introduits progressivement, là où la complexité métier le justifie réellement.
L'Event Storming
C'est l'atelier le plus efficace pour démarrer. En deux à trois heures, une équipe mixte (produit, développeurs, support, commercial) cartographie les flux métier sous forme d'événements sur un mur couvert de post-its. Sans une ligne de code, sans diagramme UML, sans contrainte technique : juste les faits métier dans l'ordre où ils se produisent. Le résultat est immédiatement exploitable pour identifier les domaines critiques, les événements clés, les zones de friction et les responsabilités floues qui généreront des bugs six mois plus tard.
Ce que ça change concrètement
Sur des projets SaaS complexes avec plusieurs années d'historique, DDD appliqué méthodiquement réduit le coût des évolutions majeures de 30 à 50 %. Pas parce que les développeurs écrivent moins de code, mais parce qu'ils en écrivent moins à refaire. Le code reflète le métier : un développeur qui rejoint le projet peut comprendre la logique business en lisant le code, sans avoir besoin d'un archéologue pour déchiffrer des abstractions techniques déconnectées de toute réalité opérationnelle.
Ce n'est pas une promesse abstraite. C'est le résultat direct d'un code dont les termes, les frontières et les invariants correspondent à ce que les experts métier ont en tête — et qu'ils peuvent valider sans interprète.