33
Page 1 Le Domain Driven Design Une conception pilotée par le domaine pour l’entreprise Sami Jaber (webmaster du site DotNetGuru.org et fondateur de DNG-Consulting)

Introduction au Domain Driven Design

Embed Size (px)

DESCRIPTION

Introduction au Domain Driven Design

Citation preview

Page 1: Introduction au Domain Driven Design

Page 1

Le Domain Driven DesignUne conception pilotée par le domaine pour l’entreprise

Sami Jaber (webmaster du site DotNetGuru.org et fondateur de DNG-Consulting)

Page 2: Introduction au Domain Driven Design

Le Symposium DNG

4 ème édition, plus de 2000 inscriptions

Présence de Bill Gates en 2005

Erik Meijer en 2008

Partenariat de longue date avec Microsoft (avec d’abord Marc Gardette et aujourd’hui François Merand)

Objectifs

Développer des sujets d’entreprise

Anticiper les évolutions des architectures de demain

Prendre du recul sur le marketing des éditeurs

Le Symposium a contribué à :

Démocratiser les architectures en couches

Faire connaître le mapping O/R, l’AOP, SOA, les pratiques agiles…

Page 3: Introduction au Domain Driven Design

Page 3

Pourquoi encore parler d’architecture en 2008 ?

De nouveaux Frameworks/API apportent une abstraction supplémentaire

Linq est une révolution « architecturale » qui produit de manière native une abstraction de la couche d’accès aux données (Linq2SQL, Linq2Entities, Linq2XML, etc …)

Mais d’autres techniques aussi

Les générateurs dynamique de codes (DynamicProxies, IL, …)

L’injection de dépendance

L’AOP

Les outils évoluent, le Design aussi

Modifie la manière de penser n-tiers

Page 4: Introduction au Domain Driven Design

Evans, Eric. Domain-Driven Design: Tackling Complexity in the Heart of Software. Addison-Wesley Professional, 2004.

Page 5: Introduction au Domain Driven Design

Avram, Abel et Marinescu, Floyd. Domain-Driven Design Quickly. Disponible gratuitement : http://www.infoq.com/minibooks/domain-driven-design-quickly.

Page 6: Introduction au Domain Driven Design

Page 6 L’architecture n-tiers traditionnelle

Couched’accès auxdonnées

Couche d’objets du domaine

CollectionsCollections

(…)(…)

XSLXSL

L’architecture n-tiers « traditionnelle »

Couche de service

PrésentationPrésentation

PartenairePartenaireDonnées

Base dedonnées

Base dedonnées

WebServices

Domaine

WebFormsWebForms

WinFormsWinForms

ASP.NETASP.NET

(…)(…)

EnterpriseEnterpriseServicesServices

WebServicesWebServices

RemotingRemoting

ThreadingThreading

ReflectionReflection

SerializationSerialization

ReflectionReflection

XMLXML

ADO.NETADO.NET

Services

BLLBLL DALDAL

Page 7: Introduction au Domain Driven Design

Exemple de service « traditionnel »

Page 7

namespace MyApplication.Services { [ServiceContract] public interface IAccountService { [OperationContract] public void Credit(Account account, double amount); } }

namespace MyApplication.Services { [ServiceContract] public interface IAccountService { [OperationContract] public void Credit(Account account, double amount); } }

public class AccountService { [OperationBehavior(TransactionRequired=true)] public void Credit(Account account, double amount) { 1) Vérification autorisation 2) Récupérer DAL et réaliser opération 3) commiter } } }

public class AccountService { [OperationBehavior(TransactionRequired=true)] public void Credit(Account account, double amount) { 1) Vérification autorisation 2) Récupérer DAL et réaliser opération 3) commiter } } } Avec l’émergence des Framework

type Linq, l’intérêt d’une couche DAL est de plus en plus discutable

Page 8: Introduction au Domain Driven Design

… et le domaine

namespace MyApplication.Domain { public class Account {

public Client Client { get { return this.client; }set {this.client = value;}

}public List EcrituresComptable {} …

}

namespace MyApplication.Domain { public class Account {

public Client Client { get { return this.client; }set {this.client = value;}

}public List EcrituresComptable {} …

}

public class EcritureComptable {

public DateTime DateEcriture { get { return this.dateEcriture; }set {this.dateEcriture = value;}

public int MontantEcriture{} } }

public class EcritureComptable {

public DateTime DateEcriture { get { return this.dateEcriture; }set {this.dateEcriture = value;}

public int MontantEcriture{} } }

De simples structures ? Syndrome du

modèle anémique

De simples structures ? Syndrome du

modèle anémique

Page 9: Introduction au Domain Driven Design

Avantages / Inconvénients

Le métier est essentiellement basé sur les services

Inconvénients :

Duplication et copier/coller dans les couches de services

Difficile parfois de mettre en place des tests unitaires

Le code des services est finalement très procédural, peu objet

La couche de service est polluée par l’infrastructure (accès aux DAO, requêtes Linq, etc ..)

Avantages :

Simple à mettre en oeuvre, mature et respecte les dépendances binaires inter-couches (aucune assembly technique à déployer côté client)

Page 10: Introduction au Domain Driven Design

Page 10L’architecture n-tiers traditionnelle

Couche InfrastructureCouche applicative

CollectionsCollections

(…)(…)

XSLXSL

L’architecture DDD

Couche du domaine

RepositoriesPrésentationPrésentation

PartenairePartenaire

Base dedonnées

Base dedonnées

Domaine

WebFormsWebForms

WinFormsWinForms

ASP.NETASP.NET

(…)(…)

EnterpriseEnterpriseServicesServices

WebServicesWebServices

RemotingRemoting

ThreadingThreading

ReflectionReflection

SerializationSerialization

ReflectionReflection

XMLXML

ADO.NETADO.NET

Factories

Services

Page 11: Introduction au Domain Driven Design

Page 11

L’ubiquitous Language et DSL

ExempleAccount Holder withdraws cash I want to withdraw cash from an ATM I can get money when the bank is closed Scenario 1: Account has sufficient funds Given the account balance is $100 And the card is valid And the machine contains enough money When the Account Holder requests $20 Then the ATM should dispense $20 And the account balance should be $80 And the card should be returned Scenario 2: Account has insufficient funds Given the account balance is $10 And the card is valid And the machine contains enough money When the Account Holder requests $20 The ATM should not dispense any money

ExempleAccount Holder withdraws cash I want to withdraw cash from an ATM I can get money when the bank is closed Scenario 1: Account has sufficient funds Given the account balance is $100 And the card is valid And the machine contains enough money When the Account Holder requests $20 Then the ATM should dispense $20 And the account balance should be $80 And the card should be returned Scenario 2: Account has insufficient funds Given the account balance is $10 And the card is valid And the machine contains enough money When the Account Holder requests $20 The ATM should not dispense any money

L’ubiquitous language est à la base du DDD

C’est un language pseudo-techniquecompréhensible par la MOA et les développeurs

Les verbes sont les méthodes, les sujets sont les objets

Tout changement dans l’UL induit un changement dans le modèle

La démarche DDD est pilotée par

Les tests (TDD)

Le refactoring

Page 12: Introduction au Domain Driven Design

Domain Driven Development

Multi-couches Couche de présentation

Couche Application (appelée aussi couche de services)- Aucune logique métier

- Ne porte pas l’état des objets du domaine

- Porte l’état d’une tâche applicative

La couche du domaine- Contient toute l’information du domaine

- L’état du domaine est ici

La couche d’infrastructure- Assure la communication entre les couches

- Assure la persistence des objets métier

- Contient les librairies ou Framework externes

Page 13: Introduction au Domain Driven Design

Les Mots-clé de l’univers DDD

Focalisé sur le domaine

Un langage unifié

Une architecture multi-couches

Entités et Value object

Services

Les modules

Agrégats (Aggregates)

Factories

Repositories

Page 14: Introduction au Domain Driven Design

Les agrégats

Plusieurs préceptes connus volent en éclat

One to many, many to many, trop complexe !

Supprimer les relations inutiles, trop de relations tuent la relation

Réduire les multiplicités et direction (éviter le bidirectionnel)

Laisser la base de données gérer les opérations de Cascade et update/delete

Utiliser les agrégats (aka aggregate)

Assure la gestion des relations entre objets

Un agrégat possède une entité comme élément racine

Seule la racine peut être obtenue à partir des requêtes objets

L’entité est responsable de maintenir les invariants (règles non liées à la modification de données)

Page 15: Introduction au Domain Driven Design

Exemple d’agrégat

Page 15

Fonctionnel : une facture est associée à un client

Un client possède une adresse

Une facture contient des lignes, associées à un produit

RacinesRacines

Page 16: Introduction au Domain Driven Design

Les Factories

La création d’un objet est parfois complexe, spécialement pour les agrégats

Utiliser des factories

Créer la racine de l’agrégat et l’ensemble des objets qui le contiennent

Création atomique

Attention à veiller à ne pas violer l’encapsulation

Possibilité d’utiliser l’ordre New() dans certains cas :

Bénéfices :

- Simplicité

- Tous les attributs peuvent être passés au constructeur

- Aucun besoin de changer d’implémentation

Page 17: Introduction au Domain Driven Design

Et la couche de services ?

Certains concepts ne sont pas naturel à un domaine en particulier, exemple :

Exporter au format CSV le contenu d’une facture

Accéder à plusieurs comptes pour réaliser un transfert de fond

Tout ce qui n’est pas de l’ordre d’un traitement lié à un objet du domaine ou à un traitement lié à l’infrastructure

La couche du domaine s’appuie sur les services (l’inverse est aussi possible)

Page 17

Page 18: Introduction au Domain Driven Design

Les Value Objects

Utilisés lorsqu’il est important de maîtriser le contenu d’un objet et non son identité

Quand écrire un VO ?

Lorsque le VO n’est pas une Entity !

Encore mieux si le VO est immuable (son contenu n’évolue pas)

Pour les performances

Pour l’intégrité des données (pas de risque de modification par erreur)

Si les VO sont partageables, ils doivent être immuables

Garder les VO “petits” et simples

Un VO peut contenir des références vers d’autres VO ou des entités

Page 19: Introduction au Domain Driven Design

Les repositories

Page 19

Le DDD comme toute philosophie multi-couches ne couple pas l’infrastructure technique au modèle du domaine

Le repository encapsule la logique permettant d’obtenir des références d’objets

Les méthodes doivent rester simples (généralement des recherches)

Une factory crée, un repository recherche.

« A factory is pure domain, a repository communicates with the infrastructure » (E. Evans)

Page 20: Introduction au Domain Driven Design

Exemple avec Linq

public interface IOrderRepository : IRepository<Order> { Order FindWithId(string orderId); ICollection<Order> FindAllOrders(); ICollection<Order> FindAllValidOrders(); bool IsUniqueOrder(string orderId); bool IsValidOrder(string orderId); }

public interface IOrderRepository : IRepository<Order> { Order FindWithId(string orderId); ICollection<Order> FindAllOrders(); ICollection<Order> FindAllValidOrders(); bool IsUniqueOrder(string orderId); bool IsValidOrder(string orderId); }

public class OrderRepositoryImpl : IOrderRepository { ICollection FindAllValidOrders(string orderId);

ICollection<Order> orders = Repository<Order>.FindAll(Where.Order.Id == orderId &&Where.Order.Status == OrderStatus.ReadyToShip &&Where.Order.Date >= DateTime.Today);

return orders; }

public class OrderRepositoryImpl : IOrderRepository { ICollection FindAllValidOrders(string orderId);

ICollection<Order> orders = Repository<Order>.FindAll(Where.Order.Id == orderId &&Where.Order.Status == OrderStatus.ReadyToShip &&Where.Order.Date >= DateTime.Today);

return orders; }

Page 21: Introduction au Domain Driven Design

Les DSL à la rescousse (exemple réalisé avec Boo)

Les DSL peuvent apporter énormément sur la partie « statique » du modèle architectural

La partie dynamique reste complexe à modéliser sans recourir au code

Page 21

Page 22: Introduction au Domain Driven Design

La big picture DDD

Page 22

Page 23: Introduction au Domain Driven Design

DDD, l’architecture idéale ?

Non. Le design idéal n’existe pas.

La force et le principal défaut du DDD est de s’appuyer sur le libre choix du concepteur

On hésite souvent entre couche de service et couche du domaine

Le lien entre couche du domaine et Repository (persistence) prête à discussion

Patterns possédant les même défauts que ceux d’Active Record

- granularité fine des services entraîne une granularité fine des requêtes SQL). Problème de N+1 (performances)

Mais la formalisation du fonctionnel par le domaine est un concept en devenir, encore peu exploité par les architecture n-tiers traditionnelles

Page 23

Page 24: Introduction au Domain Driven Design

La couche de présentationUn des enjeux majeurs de demain

Page 25: Introduction au Domain Driven Design

La couche de présentation coûte cher

On estime en moyenne que la répartition budget/couches pour une application de gestion classique coûte :

Couche d’accès aux données : 30 à 50 %

Couche de services (règles de gestion) : 30 à 50 %

Couche de présentation : 30 à 50 %

Les fourchettes s’expliquent par le type d’outils employées (générateurs de code DAL, O/R Mapping, générateur d’écrans, etc …)

Ces dernières années, énormément de progrès ont été fait pour augmenter la productivité de la couche d’accès aux données et la couche de service

Mais la couche de présentation reste à la traîne !

Page 26: Introduction au Domain Driven Design

La couche de présentation coûte cher

Et pourtant, de nombreux progrès ont été réalisés sur la partie designer :

Les éditeurs WYSIWYG (WPF Designer, WinForms Designer, ASP.NET Designer)

Des Framework de composants plus riches (vectoriels, …)

Pourquoi une telle différence ?

Encore trop de code pour réaliser le lien entre les interfaces graphiques et les objets du domaine

Historiquement, .NET a toujours privilégié le lien interfaces graphiques vers bases de données (DataSet, DataAdapter, …)

Le Binding avec les objets est en plein essor- WPF et Adobe Flex sont les plus avancés dans ce domaine

Page 27: Introduction au Domain Driven Design

Le trio gagnant

Data Binding + Validation + Converter

Page 27

80% du code induit par la couche de présentation relève de :

la validation des champs de surface (les contrôles référentiels et d’intégrité sont dans la couche de services)

la conversion des formats (date, intervalles, textes spécifiques, …)

la gestion des messages d’erreurs

Page 28: Introduction au Domain Driven Design

Le binding

Page 28

Bindé sur le détail d’une FacturePropriété : Id

Facture

Ligne

Ligne

Le Binding peut être Uni ou Bi-directionnel

Le bidirectionnel améliore la maintenabilité du code

Page 29: Introduction au Domain Driven Design

La validation et la conversion

La validation est opérée dès lors qu’une valeur convertie dans son format destination est considérée correcte

Il suffit d’annoter avec des custom Attributes le modèle du domaine pour disposer d’une puissance redoutable en terme de productivité

Page 30: Introduction au Domain Driven Design

Ce type d’architecture existe-t-elle ?

Certaines parties existent déjà en tant que telles dans :

WPF (Windows Presentation Foundation)

Adobe Flex

Windows Forms et Java Swing (Norme Beans Binding) avec un support moindre de l’autobinding (la possibilité de placer des Binding Path sur des widgets)

Les Framework Web sont plutôt à la traîne même s’ils intègrent tous des Framework de validation ou de binding (ASP.NET)

L’apport d’AJAX permet de simuler des sortes de Master/Detail réactifs

Le développement d’un (mini) Framework est nécessaire

Page 31: Introduction au Domain Driven Design

Conclusion

Le développement pilotée par le domaine ou centré sur le domaine est en plein essor

Dans l’univers .NET les outils sont prêts pour intégrer ce mode de développement

WCF pour la partie services techniques (transaction, sécurité, montée en charge)

Linq pour l’accès aux données

WPF et WinForms pour l’autobinding

Jamais la productivité du développeur n’aura été autant au centre des préoccupations des éditeurs

Après le quick & dirty, voici venu le temps du clean RAD

Page 31

Page 32: Introduction au Domain Driven Design

Page 32

Annexes

Page 33: Introduction au Domain Driven Design

Sites et liens …

Validation Application Block (Patterns & Practices) http://blogs.msdn.com/tomholl/archive/2006/11/27/validation-application-block-revealed.aspx

Microsoft Data Access blog http://blogs.msdn.com/adonet

Domain Driven Design http://www.domaindrivendesign.org/

DotNetGuru.org (actualité, articles techniques, etc …)http://www.dotnetguru.org

DDD avec .NET (Livre Applying Domain-Driven Design)Jimmy Nilsson

Page 33