2

使用 DDD 时拥有存储库的好处是,它们允许人们设计域模型而不必担心对象将如何被持久化。它还允许最终产品更加灵活,因为可以轻松地换入和换出存储库的不同实现。因此,存储库的实现可以基于 SQL 数据库、REST Web 服务、XML 文件或任何其他存储和检索数据的方法。从模型的角度来看,期望只有这些魔法集合可用于存储和检索聚合根对象。

现在,如果我有两个正常的内存集合,比如 anIList<Order>和 an IList<Customer>,我永远不会期望修改一个集合会影响另一个集合。那么相同的逻辑是否应该适用于存储库?存储库的实际实现是否应该彼此完全隔离,即使它们实际上访问同一个数据库?

例如,可以在SQL数据库中的Customers表和Orders表之间建立删除时的级联关系,以便在删除客户时删除相应的订单。但是,如果稍后将SQLCustomerRepository替换为,此功能将中断RESTCustomerRepository

那么我认为模型应该始终假设存储库彼此完全隔离,相应地,存储库的实际实现也应该隔离,这是否正确?

那么 ifOrders应该在删除时删除 aCustomer是否应该在域模型中明确定义,而不是依赖数据库?通过CustomerService.DeleteCustomer()访问当前ICustomerRepository和的方法说IOrderRepository

我想我只是很难摆脱关系世界并进入 DDD 世界。我一直想从表和 PK/FK 关系的角度来思考问题,我应该完全忽略数据库的参与。

4

4 回答 4

1

我相信你错过的一点是聚合根绘制了上下文边界。
简而言之 - 下面的东西只有与聚合根本身一起才有意义。

正如我所看到的 - 订单不是聚合根,而是存在于客户聚合根上下文中的实体。这意味着 - 不需要订单存储库,因为存储库应该是每个聚合根。所以应该只有 CustomerRepository 应该知道如何持久化 Customer.Orders。

我自己并不担心,完全忽略了存储库模式,只依赖 NHibernate ORM。正确跟踪和监视状态更改的丰富域模型比实际发送更新/选择 sql 语句的方式重要得多。

另外 -在删除内容之前三思而后行。

于 2011-06-14T10:30:09.350 回答
0

永远不要删除客户,客户不会被删除,它会变为非活动状态或其他东西。另外请不要级联删除订单,这会使您进入陌生的地方,订单处理时应始终保留。想想您的应用程序的报告,因此 110 万的收入就因为您决定级联删除而消失了。

于 2011-10-25T07:30:26.687 回答
0

每个聚合根而不是每个实体都有一个存储库,因此即使聚合根的子级的级联删除也适用于聚合根存储库,因为它仍然是隔离的。

不要级联删除或对其他聚合根有任何副作用,在应用层协调此逻辑。

于 2011-10-25T08:47:44.050 回答
0

您的域模型应该为您的域的事务操作建模。通过在您的客户实体中将订单放在客户身上,您是说当客户被删除时,他的订单也应如此。

如果您的客户上有 OrderId,那就不同了。比你有客户和订单之间的关联。在这种情况下,您是说通过在客户的 OrderId 列表中添加或删除,您是在添加或删除关联,而不是添加或删除订单。

存储库的实际实现是否应该彼此完全隔离,即使它们实际上访问同一个数据库?

是的,在大多数情况下。如果您决定同时创建 Order 和 Customer Aggregate Roots,那么您是在说它们彼此独立,并且应该被允许同时独立地更改。也就是说,您不需要在两者之间进行事务性更改。如果您只将 Customer 设为 Aggregate Root,并让它有一个 Orders 列表,那么现在您说的是 Customer 实体决定了 Orders 会发生什么,并且更改 Customer 将级联更改其 Orders。

现在在您的示例中,您似乎将客户作为聚合根。和订单作为聚合根。每个都有自己的回购。客户将拥有一个 OrderId 列表来对一对多关联进行建模。如果您删除了客户,您可以发布客户删除事件,并让与该客户相关的所有内容自行清理。

于 2014-06-17T04:56:42.583 回答