gpt4 book ai didi

domain-driven-design - 域对象中的存储库

转载 作者:行者123 更新时间:2023-12-01 13:56:53 26 4
gpt4 key购买 nike

我看到很多关于这个话题的讨论,但我无法得到令人信服的答案。一般的建议是不要在域对象中拥有存储库。聚合根呢?把操作组合对象的责任交给根不是对的吗?例如,我有一个处理发票的微服务。发票是具有不同产品的聚合根。此服务不要求提供有关个别产品的详细信息。我有 2 个表,一个用于存储发票详细信息,另一个用于存储这些发票的产品。我有两个与表相对应的存储库。我在发票域对象中注入(inject)了产品存储库。这样做有错吗?

最佳答案

根据 DDD 原则,我在您的问题中看到了一些错误。让我尝试澄清一些概念以帮助您。

首先,您提到您有一个聚合根,即发票,然后是两个不同的存储库。拥有聚合根意味着聚合所包含的实体的任何更改都应通过聚合根执行。为什么?那是因为您需要满足一些适用于这些实体关系的业务规则(不变量)。例如,给定下一个业务规则:

Winning auction bids must always be placed before the auction ends. If a winning bid is placed after an auction ends, the domain is in an invalid state because an invariant has been broken and the model has failed to correctly apply domain rules.

这里有一个由拍卖和出价组成的聚合,其中拍卖是聚合根。

如果你有一个 BidsRepository,你可以很容易地做到:

var newBid = new Bid(money);
BidsRepository->save(newBid);

并且您在未通过定义的业务规则的情况下保存出价。但是,只为聚合根设置存储库是在强制执行您的设计,因为您需要执行以下操作:

var newBid = new Bid(money);
auction.placeBid(newBid);
auctionRepository.save(auction);

因此,您可以在 placeBid 方法中检查您的不变量,如果有人想设置新的出价,则无法跳过它。之后,您可以根据需要将信息保存到任意多个表中,这是一个实现细节。

其次,你说如果将存储库注入(inject)域类是错误的。这里有一个简单的解释:

The repository should depend on the object it returns, not the other way around. The reason for this is that your "domain object" (more on that later) can exist (and should be testable) without being loaded or saved (that is, having a dependency on a repository).

基本上您的设计表明,为了获得发票,您需要提供一个 MySQL/Mongo/XXX 实例连接,这是一个基础设施细节。您的域不应该知道它是如何持久化的。您的域了解拍卖和投标场景中的行为。

这些概念只是帮助您创建更易于维护的代码,并帮助您应用最佳实践,例如 SRP(单一职责原则)。

关于domain-driven-design - 域对象中的存储库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37615250/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com