Upload
samijaber
View
13.983
Download
6
Embed Size (px)
DESCRIPTION
Introduction au Domain Driven Design
Citation preview
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)
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
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
Evans, Eric. Domain-Driven Design: Tackling Complexity in the Heart of Software. Addison-Wesley Professional, 2004.
Avram, Abel et Marinescu, Floyd. Domain-Driven Design Quickly. Disponible gratuitement : http://www.infoq.com/minibooks/domain-driven-design-quickly.
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
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
… 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
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 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
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
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
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
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)
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
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
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
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
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)
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; }
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
La big picture DDD
Page 22
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
La couche de présentationUn des enjeux majeurs de demain
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 !
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
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
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
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é
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
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
Annexes
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