Question sur l’API de conception pilotée par le domaine

Je suis nouveau à DDD et je travaille sur mon premier projet, qui concerne un processus d’enregistrement de sorties de golf en ligne. mes exigences sont assez simples. les utilisateurs s’inscrivent pour la sortie et peuvent éventuellement append un quatuor. ils peuvent également parrainer un trou avec un message et quelques autres choses, mais je veux commencer par hacher nos quatre trucs.

donc, mon premier si mon agrégat contient une entité d’enregistrement, un object de valeur à quatre (qui contient un nom d’équipe et 4 objects de valeur de joueur).

lors de la conception de l’API, je pense au pseudo code suivant:

Registration reg = new Registration(); Foursome foursome = reg.CreateFoursome("My Team"); foursome.Player1.Assign("John Doe", 5, ShirtSize.XL); reg.Register(); 

Ma question est la suivante: l’un des composants internes de l’agrégat est exposé au code client, puis-je m’ouvrir à des problèmes? des défauts avec cette conception simple ou alternative apis?

toute aide serait formidable car je suis dans un état de paralysie de l’parsing en ce moment!

Merci

Pour un premier coup, ce n’est pas mauvais. Il est important lors du démarrage de la conception de ne pas trop s’attarder aux petits détails. Le temps que vous passerez à vous préoccuper de la robustesse de la conception constituera avant tout un facteur d’importance du projet. Vous apprendrez continuellement au fur et à mesure que vous construisez et, au fil du temps, votre ancien code nécessitera un refactoring pour permettre de nouveaux détails.

Prenons, par exemple, votre classe FourSome, je suppose, a quatre joueurs. Pourriez-vous plutôt avoir une classe Team ayant une contrainte de taille, telle qu’une collection de joueurs puisse être contrainte à ce nombre de joueurs? Devrait-il y avoir une classe de joueur (ou peut-être est-ce le type de Player1?)?

Les réponses à ces questions auront des conséquences sur l’extensibilité de votre système.

Je vous encourage à écrire chacun de vos scénarios dans des tests (vous pouvez également utiliser des user stories ou des cas d’utilisation, mais les développeurs aiment écrire du code). Lorsque vous écrivez les tests, complétez l’implémentation des classes Registration, Player et Foursome / Team. faire réussir les tests. Au fur et à mesure que vous développez votre système, vos tests vont changer, tout comme votre conception.

Post-ajout 1:

La conception pilotée par domaine se veut une approche pour développer les classes et les structures de données que votre application utilisera de manière à “modéliser” le domaine à problème. Dans votre cas, vous travaillez avec un système d’enregistrement de sorties de golf. Par conséquent, lorsque vous réfléchissez aux entités qui pourraient constituer un tel système, vous pourriez décrire comment un capitaine d’équipe enregistre son équipe (y compris les autres joueurs) en fournissant son inscription. L’inscription peut concerner un événement qui peut lui-même comporter des détails tels que l’organisateur, le sponsor, etc. Comme vous le voyez, chacun des noms “en majuscule” devient votre entité (classe). Au moins pour le premier projet de votre conception. Au fur et à mesure que vous découvrirez plus d’informations sur les relations entre vos classes, en particulier sur la manière dont elles interagissent (un joueur est ajouté à une équipe), vous allez étoffer les méthodes de votre classe.

Pendant ce processus, vous pouvez introduire par inadvertance des défauts de conception. Par exemple, un FourSome est, techniquement, un type d’équipe limité à quatre joueurs. Est-il judicieux de dériver une classe d’équipe et de définir une limite de quatre joueurs ou d’imposer une contrainte à l’équipe? C’est une décision de conception déterminée par … vos règles d’entreprise et vous-même. Est-ce une erreur de prendre une approche sur l’autre? Le temps nous le dira, car vous devrez constamment refactoriser votre système pour développer le système.

Vous trouverez de nombreux modèles au cours de votre processus de conception susceptibles de faciliter votre processus de conception, mais un nouveau concepteur n’a généralement pas l’expérience nécessaire pour savoir quand les utiliser. Si vous le faites, bravo à vous. Vous ne trouverez pas un design parfait la toute première fois que vous concevez. Je regarde toujours en arrière (15 ans maintenant) des designs que je trouvais géniaux, et secoue la tête face à mon exubérance juvénile.

Vous devriez décrire votre problème (pour vous-même ou sur papier). Soulignez les noms. Ce sont vos classes de candidats. Racontez une histoire pour chaque interaction utilisateur avec le système, et les verbes devraient vous aider à comprendre quelles sont les méthodes de chaque classe. Évitez d’utiliser l’enregistrement pour effectuer tout le travail, mais séparez la responsabilité des classes en fonction des besoins. Par exemple, vous pouvez append un joueur à une équipe ou faire en sorte qu’un joueur s’ajoute à une équipe. Déterminer où cette responsabilité incombe devrait être guidé (mais pas dicté) par le PRS, entre autres directives de conception.

Enfin, il n’y a pas de bonne réponse dans la conception. Je pourrais vous dire que, compte tenu de ma vaste expérience en matière de conception mais de mon expérience limitée en matière de golf, je pense que cela devrait être le cas, mais votre meilleure conception dépend en définitive des fonctionnalités, de la scope et des objectives de conception (tels que l’extensibilité). Commencez avec votre meilleur tir, écrivez des tests, et vos défauts de conception apparaîtront avant que vous ne le sachiez. :RÉ

Post-révision 2:

Je pense que vous lisez trop dans les conseils d’Eric Evan. Je ne crois pas qu’il dit que vous ne pouvez pas exposer Player from Foursome.

Commençons par la définition de l’ agrégat:

Groupe d’objects associés traités comme une unité aux fins de la modification des données . Les références externes sont limitées à un membre de l’agrégat, désigné comme racine. Un ensemble de règles de cohérence s’applique dans les limites de l’agrégat.

L’agrégat est un groupe d’objects que vous ne voudriez pas que plusieurs utilisateurs modifient en même temps, car cela risquerait de détruire les invariants de domaine. L’agrégat est également une unité de cycle de vie. Il est difficile de répondre à votre question sans savoir en quoi consistent ces invariants, ces règles de cohérence et de cycle de vie. La création de deux Foursomes sur le même enregistrement serait-elle mauvaise? Le quatuor avec Player1 non atsortingbué serait-il invalide / incohérent? Un appel à l’object Register on Registration ne serait-il pas “corrompu”? Si l’une des réponses est vraie, vous ne devez pas exposer vos objects de cette manière. Ce code doit être caché dans votre agrégat.

Il semble également que Foursome n’est pas un object de valeur car il est mutable. C’est peut-être une entité qui devrait être protégée par la racine d’agrégat d’enregistrement.

 // PlayerInfo is a value object public static Registration CreateNew(Ssortingng foursomeName, PlayerInfo player1, ...) { if (foursomeName == null) { throw new ArgumentNullException("foursomeName"); } if (player1 == null) { throw new ArgumentNullException("player1"); } Registration reg = new Registration(); Foursome foursome = reg.CreateFoursome("My Team"); foursome.Player1.Assign(player1); if(player2 != null) { foursome.Player2.Assign(player2); } reg.Register(); // return consistent and valid Registration instance return reg; } 

Encore une fois, cela peut ne pas être ce que vous voulez, cela dépend vraiment de votre modèle de domaine. Peut-être que votre racine d’agrégat devrait être une entité comme FoursomeRegistartion. Peut-être que les joueurs sont eux-mêmes agrégés s’ils peuvent exister en dehors de la limite de Foursome / Registration. Comme d’autres l’ont dit, il est difficile d’avoir un bon modèle du premier coup. Avoir une première implémentation et refactorisation en continu.