Many-to-many relationships in DDD

时光总嘲笑我的痴心妄想 提交于 2020-05-24 10:43:29

问题


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!

Class diagram


回答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: Proposed new class diagram




回答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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!