
Introduction
Dans notre dernier article, nous avons exploré les principes de Clean Architecture et la manière elle permet de construire des applications robustes, maintenables et testables. Nous allons faire un focus sur le Domain et comment l’implémenter avec un concept qui s’intègre bien à cette architecture : le Domain-Driven Design (DDD) d’Eric Evans.
Disclaimer : Si vous n’avez pas lu le précédent article, je vous encourage vivement à le faire avant de poursuivre, car il pose les bases architecturales sur lesquelles nous allons construire notre découverte du DDD.
L’histoire et les principes fondamentaux du DDD
Le Domain-Driven Design n’est pas une nouvelle technologie ni un framework à proprement parler. Il s’agit d’une approche de la modélisation logicielle qui a été formalisée par Eric Evans dans son livre “Domain-Driven Design: Tackling Complexity in the Heart of Software” publié en 2003.
Avant cela, les développeurs se concentraient souvent sur l’implémentation technique avant de réellement comprendre le problème métier qu’ils cherchaient à résoudre. On parle alors d’approche Inside-Out, ou encore d’école de Chicago que nous évoquerons dans un prochain article dédié au Test Driven Development (TDD).
Le DDD a changé la donne. Il place le domaine métier (ou simplement “Domain”) au cœur du processus de développement. C’est un changement radical qui force à comprendre d’abord le métier, puis de construire une solution technique autour.
À quoi ça sert ?
Le but principal du DDD est d’aligner le code avec la réalité du domaine métier à modéliser. Pour bien comprendre, imaginons le développement d’une application pour une compagnie maritime. Il ne suffit pas de savoir comment implémenter des listes, des graphiques ou des formulaires : il faut comprendre les concepts clés.
Qu’est-ce qu’un “navire” ? Un “cargo” ? À quoi correspond un itinéraire, un port, etc ?
Le DDD aide à traduire cette compréhension en un modèle logiciel précis et cohérent. Détaillons ensemble les grands principes :
Ubiquitous Language (Langage Omniprésent) : C’est LE principe fondamental du DDD. Il consiste à créer un vocabulaire commun entre les développeurs et les experts métier, utilisé dans toutes les conversations, la documentation et le code.
Domain Model (Modèle du Domaine) : Représentation conceptuelle du domaine métier. On ne parle pas de diagramme UML mais d’un diagramme portant les concepts clés et leurs interactions.
Bounded Contexts (Contextes Délimités) : Un domaine complexe est rarement monolithique. Le DDD cherche à mettre en lumière les frontières entre les “sous-domaines” afin de limiter la complexité excessive. Chaque contexte possède son propre modèle du domaine et son propre langage omniprésent.
Entities (Entités) : Objets disposant d’une identité unique et persistante dans le temps. Par exemple, un client clairement identifié à l’aide d’un identifiant unique est une entité.
Value Objects (Objets Valeur) : Objets définis par leurs attributs plutôt que par leur identité. Un montant d’argent ou une adresse en sont de bons exemples. Ils sont immuables et égaux en fonction de leurs valeurs.
Aggregates (Agrégats) : Regroupement d’entités et d’objets valeur traités comme une seule unité. Un agrégat possède une entité racine responsable de la cohérence des données. Par exemple, une facture peut être considérée comme une entité racine d’un agrégat : les lignes la composant, les remises, les totaux, etc. sont des éléments cohérents, n’ayant pas d’existence en dehors de la facture “racine”.
Repositories (Dépôts) : Abstractions permettant d’accéder aux données persistantes. Ils servent de découpler le modèle du domaine et la couche d’infrastructure, en plus de faciliter les tests unitaires.
Domain Services (Services du Domaine) : Opérations qui ne sont pas naturellement associés à une entité ou un objet valeur spécifique, comme par exemple un service de calcul de frais de port.
Ci-dessous le diagramme extrait de l’excellent livre DDD Vite Fait (Domain-Driven Design Vite fait - InfoQ) résumant les interactions des éléments de DDD.

Implémentation de DDD en .Net
Maintenant que nous avons posé les bases théoriques, découvrons un exemple simple d’implémentation du DDD en .Net, en mettant l’accent sur la couche Domain de notre Clean Architecture.
Rappelons que la Clean Architecture vise à isoler la logique métier des détails d’implémentation (frameworks, bases de données, etc.).
Exemple : Gestion de commandes
Imaginons un système simple de gestion de commandes dont voici quelques éléments clés du modèle du domaine :
Client : Un agrégat qui représente un client par lequel on pilote ses commandes, son pourcentage de remise. Il ne peut y avoir de commande sans client, c’est une des racines de notre domaine.
Commande : Une entité disposant d’un ID unique, d’une date de création, d’un client et d’une liste de produits (ligne de commande).
Produit : Une entité avec un ID unique, un nom, un prix et une quantité en stock.
LigneDeCommande : Un objet valeur représentant la quantité d’un produit spécifique dans une commande.
CalculateurPrixService : Un service chargé de calculer le prix total d’une commande en tenant compte des remises propre au client.
Points clés
Pureté du domaine : Le code ci-dessus se situe dans la couche Domain et ne dépend d’aucune autre couche de l’architecture.
Responsabilité unique : Chaque classe porte une responsabilité claire et bien définie.
Testabilité : Le découplage apporté par l’utilisation d’interfaces (comme ICommandeRepository) facilite les tests unitaires. Il est ainsi possible de simuler le repository afin de tester la logique métier sans dépendre d’une base de données.
Langage omniprésent : Les noms des classes et des méthodes reflètent le vocabulaire du domaine.
Avantages et inconvénients du DDD
Avantages
Compréhension du Domaine : Le processus de modélisation impose une compréhension approfondie du domaine métier, car il oblige à identifier les différents éléments et leurs interactions.
Maintenabilité : La pureté du domaine, la qualité de la conception et l’usage du langage omniprésent permettent de mieux comprendre le code (en particulier la couche Domain) et facilitent ses modificationsdans le temps.
Communication : Le langage omniprésent simplifie les échanges entre les experts métier et les développeurs, qui parlent un language commun.
Inconvénients
Complexité : La mise en place du DDD, tant au sein des équipes que du code, est plus complexe qu’une approche plus classique. Cette méthode de conception est surtout adaptée à des problématiques métiers complexes.
Montée en compétence : Elle nécessite un investissement en temps pour assimiler les concepts et principes du DDD.
Risque de sur-ingénierie : Il existe un risque de tomber dans le piège de sur-ingénierie si on applique le DDD à un problème qui n’en a pas besoin.
Conclusion
Le Domain-Driven Design, associé à Clean Architecture, offre une approche efficace pour construire des applications complexes. En plaçant le métier au cœur du processus de développement et en isolant la logique métier des détails d’implémentation, il devient possible de créer des systèmes plus robustes, plus maintenables et alignés sur les besoins réels des utilisateurs.
Comme pour l’article consacré à la Clean Architecture, j’insiste sur le fait que le DDD n’est pas une solution miracle. Appliqué aux bons projets, et au sein des bonnes équipes, il peut transformer drastiquement la manière de concevoir et de développer.
À l’inverse, lorsqu’il est mal mis en œuvre, il peut aussi engluer les équipes dans une conception bancale, pénalisant aussi bien les développeurs que les experts métier.
Dans un prochain article, nous poursuivrons notre exploration des méthodes de conception et d’architecture en mettant le cap sur un aspect essentiel : les tests, avec le Test-Driven Development (TDD).
Sources
Domain-Driven Design: Tackling Complexity in the Heart of Software par Eric Evans
Implementing Domain-Driven Design par Vaughn Vernon
Domain-Driven Design Vite fait - https://www.infoq.com/fr/minibooks/domain-driven-design-quickly/