2010-07-02 7 views
2

Faire un peu de lecture autour de la conception axée sur le domaine et il semble que vous êtes censé accéder à toutes les entités au sein d'un agrégat par traversal de la racine globale.Traversant agrégats

Cependant, en même temps, vous devriez vraiment essayer de résumer vos données afin que les propriétés/champs sont protégés ou privés.

donc ma question est la suivante: Si les champs sont protégés comment/privé vous sont censés traverser l'ensemble?

La façon dont je l'ai mis en place à l'heure actuelle est la suivante: je marque toutes les propriétés de mon modèle de domaine en interne avec les méthodes de « réglage » marqués comme protégés. De cette façon, au moins rien en dehors du modèle ne peut accéder aux propriétés, mais les objets dans le modèle peuvent accéder à d'autres propriétés d'objets et je permets seulement de définir les propriétés à partir de l'objet lui-même. Même si j'ai fait cela, j'ai toujours l'impression que cela ne devrait s'appliquer qu'aux propriétés d'autres entités agrégées (le "nom" d'un client serait toujours privé, mais leurs "Commandes" devraient être marquées comme interne pour permettre la traversée du Client -> Commandes -> etc.)

Quelqu'un a-t-il des conseils à ce sujet?

EDIT:

Je vais essayer de donner un exemple plus concret pour la question suivante: J'ai deux objets dans mon graphe d'objet: Bibliothèque et livre. Disons pour cet exemple que Bookshelf est la racine agrégée, et que les livres sont stockés sur une étagère, donc ne sont que des entités dans l'agrégat (Bookshelf a une collection de livres).

Je veux écrire une méthode pour ajouter un nouveau livre à la bibliothèque. Suivant les meilleures pratiques DDD, je crois que je devrais écrire une méthode sur la classe Bookshelf comme AddBook (Livre de livre).

Toutefois, que se passe-t-il s'il existe un besoin métier qu'aucun livre portant le même titre ne puisse être ajouté à la bibliothèque? Je veux une certaine logique dans la méthode Bookshelf.AddBook pour vérifier la collection de livres pour s'assurer que ce livre n'existe pas déjà. Le problème est maintenant que je ne peux pas faire cela car j'ai écrit l'objet Book d'une manière bien encapsulée et sa propriété "Name" n'est pas accessible au public. Je comprends que c'est un exemple plutôt artificiel, mais j'espère que cela illustre mieux le problème. Je réalise aussi maintenant que ce n'est pas seulement un problème DDD, mais un problème d'encapsulation OO en réalité. Je suis sûr qu'il doit y avoir une manière très commune et facile de résoudre ce que j'essaie de faire et je le pense massivement.

Répondre

2

Il n'y a rien de mal à exposer les propriétés dans le cas d'une relation semblable à une composition entre parent et ses enfants. Les propriétés enfants sont exposées au parent, mais parce que leur relation forte et leur interdépendance ne font pas obstacle à l'encapsulation. En d'autres termes, il n'y a rien de mal à exposer la propriété name de Book à la bibliothèque, mais il serait faux (au sens des meilleures pratiques de DDD) d'exposer le nom de Book à d'autres agrégats. Il serait également faux d'exposer la collection modifiable de livres. Exposer la collection en lecture seule doit être fait avec prudence - cela peut être le signe d'une rupture de l'encapsulation.

Est-ce que cela répond à votre question?

+0

Il répond à la question, et je suppose que c'est ce que je voulais dire en disant que je pensais trop - c'est aussi simple que de détendre légèrement les règles et de rendre la propriété disponible, mais seulement dans l'ensemble. La question qui se pose est de savoir quelles fonctionnalités du langage C# utiliseriez-vous pour permettre l'accès au Nom du livre à la bibliothèque, mais pas aux classes en dehors de cet ensemble? (Penser à cela en termes de différents agrégats pour un contexte borné étant dans un assemblage de C#) – Justin

-1

Le Visitor pattern est le mécanisme traversal typique.

+0

Ce n'est pas tout à fait le type de traversée que je pense ici. Le modèle de visiteur me permettrait de traverser le graphe d'objets et d'effectuer une action sur chaque noeud du graphe. Cependant, je parle juste de référencer les objets contenus de l'entité parente - par exemple: var customerOrderLineItems = customer.Orders [0] .OrderLines; – Justin

+0

Vous avez plusieurs choix. Tout d'abord, certains croient que vous ne devriez pas "atteindre" des objets comme ça. C'est une indication que vous traitez le graphe d'objets comme des détenteurs de valeur muette plutôt que comme des entités autonomes et auto-gérées. Si une opération est suffisamment intégrée à une classe, elle devrait être une opération sur la classe, en déléguant à des objets contenus privés si nécessaire. Si vous avez besoin d'un système découplé à double répartition, alors le modèle de visiteur est la voie à suivre. Toute autre approche lie plusieurs méthodes à plusieurs objets dans un ensemble de relations N * M: un problème de maintenance. –