问题
I'm new to DDD and I'm stuck with many-to-many relationships. E.g. we have two aggregate roots - Tasks and Workers.
Contract is definitely not aggregate root, because it has no sense without Task and Worker. So, it should be part of some aggregate. But which aggregate should it belong to? We need to know both summary costs of all task contracts and summary costs of all worker contracts. And it's natural for me to have contracts collection both in Task and in Worker.
Well, I can move Costs calculation to domain service, but I afraid it's a step forward to anemic model. Is there common way to deal with many-to-many relationships and preserve reach domain model?
Thanks!
回答1:
By following related questions linked in the sidebar, I found this interesting article:
DDD & Many to Many Object Relational Mapping
It seems to recommend what I was intuitively thinking anyway: that it is not in fact natural for worker and task to take on a dependence on contract. That is, the concept of a "worker" is still meaningful without the concept of a "contract" (and similarly for task), so the entity embodying that concept should not have a dependency on the contract entity.
To display the contracts assigned to a given task, or the contracts assigned to a given worker, you will need to run a domain query. This is in fact an appropriate use for a domain service, and better reflects the reality of your domain if you think about it.
I also note that you say "Contract is definitely not aggregate root, because it has no sense without Task and Worker." That is actually the precise reason that Contract is the aggregate root.
So, my suggestion, with arootbeer's insight from the comments incorporated:
回答2:
Contract
appears to me to be a first-class object in your design. Your claim that it doesn't make sense outside of the context of both a worker
and a task
is certainly true, but that doesn't mean it isn't an aggregate root in its own right.
Presumably Contract
has its own logic for calculating its cost, based on some attributes of the task
and worker
associated with it. Similarly, there is context that Task
and Worker
contain that are not relevant to Contract
.
The gap you need to jump is moving the relevant context into the Contract
object. Let it store the worker
's rate, and the task
's period (in addition to the respective IDs, which are only modeled implicitly above), and calculate cost dynamically.
--EDIT--
As Domenic states, your comment is a good candidate for a follow-up question. But I will say that once you get the Task
and Worker
IDs onto the Contract
, reporting becomes a trivial task.
来源:https://stackoverflow.com/questions/5806120/many-to-many-relationships-in-ddd