domain-driven-design - 我应该如何强制聚合根之间的关系和约束?

标签 domain-driven-design aggregate aggregateroot

关于 DDD 模型中两个聚合根之间的引用之间的关系,我有几个问题。请参阅下图所示的典型客户/订单模型。

enter image description here

首先,聚合的实际对象实现之间的引用是否应该总是通过 ID 值而不是对象引用来完成?例如,如果我想要有关订单客户的详细信息,我需要获取 CustomerId 并将其传递给 ICustomerRepository 以获取客户,而不是设置订单对象以直接返回客户是否正确?我很困惑,因为直接返回客户似乎会使针对模型编写代码更容易,并且如果我使用像 NHibernate 这样的 ORM,设置起来并不难。然而,我相当肯定这将违反聚合根/存储库之间的界限。

其次,应该在哪里以及如何对两个聚合根执行级联删除关系?例如,假设我希望在删除客户时删除所有关联的订单。 ICustomerRepository.DeleteCustomer() 方法不应该引用 IOrderRepostiory 吗?这似乎会打破聚合/存储库之间的界限?我是否应该有一个 CustomerManagment 服务来处理删除客户及其关联的订单,这将引用 IOrderRepository 和 ICustomerRepository?在这种情况下,我如何确定人们知道使用服务而不是存储库来删除客户。这仅仅是教育他们如何正确使用模型吗?

最佳答案

First, should references between aggregates always be done through ID values and not actual object references?



不是真的——尽管有些人会出于性能原因做出这种改变。

For example if I want details on the customer of an Order I would need to take the CustomerId and pass it to a ICustomerRepository to get a Customer rather then setting up the Order object to return a Customer directly correct?



通常,您会为关系的一侧建模(例如 Customer.OrdersOrder.Customer )以进行遍历。另一个可以从适当的存储库中获取(例如,CustomerRepository.GetCustomerFor(Order)OrderRepository.GetOrdersFor(Customer))。

Wouldn't that mean that the OrderRepository would have to know something about how to create a Customer? Wouldn't that be beyond what OrderRepository should be responsible for...


OrderRepository会知道如何使用 ICustomerRepository.FindById(int) .您可以注入(inject) ICustomerRepository .有些人可能对此感到不舒服,并选择将其放入服务层——但我认为这太过分了。没有什么特别的原因,存储库不能相互了解和使用。

I'm confused because returning a Customer directly seems like it would make writing code against the model easier, and is not much harder to setup if I am using an ORM like NHibernate. Yet I'm fairly certain this would be violating the boundaries between aggregate roots/repositories.



聚合根可以保存对其他聚合根的引用。事实上,任何东西都可以持有对聚合根的引用。但是,聚合根不能保存对不属于它的非聚合根实体的引用。

例如,Customer不能包含对 OrderLines 的引用- 因为OrderLines正确地属于 Order 上的一个实体聚合根。

Second, where and how should a cascade on delete relationship be enforced for two aggregate roots?



如果(我强调如果,因为这是一个特殊要求)实际上是一个用例,则表明 Customer应该是您唯一的聚合根。然而,在大多数实际系统中,我们实际上不会删除 Customer已关联 Order s - 我们可能会停用它们,移动它们的Order s 到合并的 Customer等 - 但不是彻底删除 Order s。

话虽如此,虽然我不认为它是纯 DDD,但大多数人会在遵循删除 Order 的工作单元模式时允许一些宽大处理。 s 然后是 Customer (如果 Order 仍然存在,则会失败)。你甚至可以拥有 CustomerRepository如果您愿意,可以做这项工作(尽管我更愿意自己更明确地说明)。允许孤立的 Order 也是可以接受的。 s 稍后清理(或不清理)。用例在这里发挥了重要作用。

Should I instead have a CustomerManagment service which handles deleting Customers and their associated Orders which would references both a IOrderRepository and ICustomerRepository? In that case how can I be sure that people know to use the Service and not the repository to delete Customers. Is that just down to educating them on how to use the model correctly?



对于与存储库密切相关的东西,我可能不会走服务路线。至于如何确保使用服务......你只是不要公开DeleteCustomerRepository .或者,如果删除 Customer,则会引发错误。会成为孤儿Order s。

关于domain-driven-design - 我应该如何强制聚合根之间的关系和约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6118174/

相关文章:

java - Spring data rest领域驱动设计-发布非聚合根实体

R表函数: how to sum instead of counting?

c# - 使用聚合连接 linq 将结果放入 POCO

architecture - 每个命令的事件溯源再水合?

asp.net-mvc - ASP.NET MVC NHibernate 模型绑定(bind)

domain-driven-design - DDD 和 CQRS : use multiple repositories from a single command handler?

domain-driven-design - CQRS 对我的域是否正确?

sql-server - 慢速 SQL Server CLR 聚合

orm - 绕过聚合根来编辑单个模型

hibernate - DDD : how to properly implement with JPA/Hibernate entities relation?