DDD avec ORM où doit aller la logique métier?

10

J'ai utilisé un outil MDA (model driven architecture) dans le passé où nous avons modélisé via UML et cela a généré les entités commerciales (notre modèle de domaine) et l'ORM (mapping, etc.) entre autres.

Une grande partie du code d'entreprise et des services travaillant sur le domaine faisaient partie du modèle et nos référentiels renvoyaient les entités commerciales (il aurait donc été impossible de passer à un autre ORM (pas ce que nous voulions)).

Cependant, maintenant je commence un projet et je veux penser en termes de DDD.

Jusqu'à présent, j'ai l'impression de mettre ma logique métier dans mon modèle de domaine et via des référentiels, je travaillerais avec l'ORM (que j'ai choisi). Cependant, si je voulais continuer à utiliser l'outil MDA pour la partie ORM de l'application, le modèle créé ici serait très anémique (c'est-à-dire qu'il ne contiendrait aucune logique métier). De même, si j'utilisais Entity Framework (.net) ou NHibernate pour mon ORM, ce serait aussi un modèle anémique.? Je ne sais pas où vous mettriez la logique commerciale si je viens d'utiliser NHibernate.

Ai-je raison de penser de cette façon, en d'autres termes avec DDD toute la logique métier du domaine et d'utiliser simplement l'ORM pour la persistance via les référentiels?

JD01
la source

Réponses:

12

il aurait donc été impossible de passer à un autre ORM (pas que nous voulions)).

Cela semble faux. Un avantage majeur du modèle de référentiel est que vous masquez la logique d'accès aux données et qu'elle est facilement échangeable.

Jusqu'à présent, j'ai l'impression de mettre ma logique métier dans mon modèle de domaine et via des référentiels, je travaillerais avec l'ORM (que j'ai choisi). Cependant, si je voulais continuer à utiliser l'outil MDA pour la partie ORM de l'application, le modèle créé ici serait très anémique (c'est-à-dire qu'il ne contiendrait aucune logique métier). De même, si j'utilisais Entity Framework (.net) ou NHibernate pour mon ORM, ce serait aussi un modèle anémique.? Je ne sais pas où vous mettriez la logique commerciale si je viens d'utiliser NHibernate.

Un modèle de domaine anémique est considéré comme une mauvaise pratique par beaucoup, par exemple par Martin Fowler. Vous devez éviter une telle conception car un tel modèle conduit à des techniques de conception procédurales plutôt qu'à une bonne conception orientée objet. Vous avez ensuite des classes de données et des classes de gestionnaire / traitement, ce qui signifie que vous avez séparé l'état et le comportement. Mais un objet devrait vraiment être "état et comportement".

NHibernate fait un excellent travail à l'ignorance de la persistance. Vous pouvez masquer les détails du mappage en XML ou avec FluentNHibernate et simplement écrire des POCO simples. Il est très facile de créer un modèle de domaine riche avec NHibernate. Je pense que vous pouvez aussi le faire avec le framework d'entité et l'outil MDA. Tant que cet outil produit des classes partielles, vous pouvez étendre le code généré assez facilement sans avoir à vous soucier qu'une nouvelle génération pourrait détruire votre code écrit par l'utilisateur.

Pour abréger cette longue histoire. Lorsque vous utilisez NHibernate, rien, je ne répète rien , vous empêche d'embrasser un modèle de domaine riche. Je recommande de l'utiliser avec FluentNHibernate et de cartographier à la main. L'écriture du code de mappage ne prend que 5 à 10 minutes. Je suppose que la même chose est vraie pour le framework d'entité et que ses outils créent au moins des classes partielles facilement extensibles.

Ai-je raison de penser de cette façon, en d'autres termes avec DDD toute la logique métier du domaine et d'utiliser simplement l'ORM pour la persistance via les référentiels?

Pour la plupart, vous avez raison. Vous devriez avoir un modèle de domaine riche. Surtout lorsque les choses deviennent de plus en plus complexes, il est plus facile à entretenir et à étendre lorsque vous les avez conçues correctement. Mais gardez à l'esprit que DDD connaît également les services (couche de domaine et couche d'application) pour implémenter la logique métier et les usines pour encapsuler la logique de création.

J'ai également tendance à différencier la logique métier en logique de domaine et en logique métier d'application réelle. La logique du domaine est la façon dont le domaine interagit et se comporte tandis que la logique d'application, qui est une couche complètement différente, encapsule la façon dont le domaine est utilisé pour le cas d'utilisation / l'application spécifique. Souvent, je dois mettre à jour le modèle de domaine pour prendre en charge des cas d'utilisation spécifiques et le rendre plus puissant.

Faucon
la source
2
+1: Je sépare également la couche logique de domaine de la couche logique d'application. J'ai mis tout l'ORM et la base de données dans la couche logique du domaine. La couche logique d'application ne sait rien de l'ORM, des transactions et de tout ça: elle ne voit que les classes de logique métier et appelle leurs méthodes. Je trouve cette approche très efficace pour avoir une couche logique d'application plus simple et plus propre.
Giorgio
@Falcon: Merci pour l'info. Lorsque j'ai mentionné le modèle anémique, ce que je voulais dire, c'est que si je créais un domaine à l'aide de DDD, une version de mes référentiels serait peut-être la version mda où je déplacerais simplement mes entités vers les entités mda (c'est-à-dire le modèle anémique), puis les persisterais dans les transactions, etc. Est-ce que ça va? Je doute que j'utiliserai l'outil MDA, mais j'essaie simplement de comprendre comment je pourrais le faire si je le voulais. Est-ce que ça sonne bien?
JD01
@ JD01: Je ne vous comprends pas très bien, mais il semble que vous souhaitiez transformer des entités de modèle de domaine afin de pouvoir les conserver facilement. C'est un peu comme utiliser des DTO et un automappeur (google it) pourrait être un outil utile pour une telle tâche. Une telle approche n'interfère pas nécessairement avec les meilleures pratiques DDD. Après tout, les référentiels sont également destinés à masquer la logique d'accès aux données. Vous pouvez simplement transformer vos objets métier en arrière-plan en DTO MDA, puis les conserver et l'utilisateur de l'API ne le remarquera même pas. Je pense que ça va.
Falcon
1
@ JD01: Je vous suggère de jeter un œil au lien suivant pour voir combien de gars Enterprise Java le font. Ils ont essentiellement un DAO, un DTO et un BO (objet métier). Pour moi, c'est trop de couches mais le design est correct. java.sun.com/blueprints/corej2eepatterns/Patterns/…
Falcon
@ Falcon: Oui, je pensais comme les DTO étant mes objets MDA, pas que j'irais dans ce sens. Juste avoir une idée de ce que chaque partie des joueurs DDD d0. Encore merci.
JD01
3

Cependant, si je voulais continuer à utiliser l'outil MDA pour la partie ORM de l'application, le modèle créé ici serait très anémique (c'est-à-dire qu'il ne contiendrait aucune logique métier).

Je ne sais pas quel outil MDA vous utilisez, mais ceux avec lesquels j'ai travaillé créent toujours des classes partielles, vous êtes donc libre de les compléter avec autant de logique métier que vous le souhaitez.

Cependant, je pense que les outils MDA sont un peu moins appropriés dans un contexte DDD que les ORM, car la génération de code a souvent tendance à produire des classes brouillées avec du bruit spécifique à l'outil au lieu des entités de domaine rationalisées et clairement exprimées que nous attendons. En fait, ce que vous obtenez souvent est un mélange de données de domaine, de logique de persistance, de logique de validation de contrainte ... et je ne sais pas s'il existe un moyen de séparer ces problèmes avec la plupart des outils MDA.

Et bien sûr, vous ne pouvez pas toucher le code généré sauf via des classes partielles, ce qui signifie que vous ne pouvez pas éliminer les comportements anti-DDD potentiels qui seraient intégrés. Cela pose problème dans une approche où vous souhaitez appliquer des barrières strictes entre les agrégats et adapter parfaitement les relations entre vos entités. Le temps de génération dans un environnement d'intégration continue peut également souffrir de l'étape de génération de code supplémentaire.

En dehors de cela, je pense que Falcon a à peu près tout dit - absolument rien dans les outils ORM ou MDA ne vous empêche d'avoir des entités de domaine riches.

guillaume31
la source
Bonjour, j'utilise ECO (objets de base d'entreprise) de capableobjects.com et c'est exactement comme vous l'avez décrit.
JD01
1

Ce que je fais dans mon équipe est de modéliser mon objet, mon domaine et d'ajouter ma logique métier en même temps. Je n'utilise pas le développement piloté par modèle qui générerait un code à partir d'un modèle, mais je préfère l'approche d'annotation. Je veux dire qu'au niveau de l'objet à l'intérieur du diagramme de classe j'ajoute des stéréotypes ORM. Cela ajoutera des annotations de persistance directement dans le code qui sont compatibles avec EJB3 / hibernate. La création de la base de données est effectuée par Hibernate et certainement pas par les modèles UML. C'est beaucoup mieux parce que si le code change et que les annotations ajoutées ne sont pas exactement ce que le spécialiste de l'hibernation peut alors changer, mais le modèle est toujours bon. Je peux également modifier mes exigences et mon modèle de domaine est toujours correct.

Les développeurs peuvent ajouter une logique métier à l'intérieur de chaque méthode et ajouter un commentaire, je peux également modéliser et ajouter des contraintes. Par exemple, les ventes devraient être supérieures à 50k sinon etc ... Je n'ai pas besoin de le coder mais d'écrire simplement le modèle et cette information serait visible pour l'équipe de développeurs. UML vraiment cool et flexible.

UML_GURU
la source