我猜答案基本上是“视情况而定”。
在领域驱动设计 (DDD) 中,我们努力根据对我们工作领域中实际发生的情况以及我们开发的应用程序将如何解决业务的共同理解来对领域进行建模。 em> 问题。
如果在域中实际上有 30 多个对 Doc 的引用(隐式或显式,见下文),那么是的,在删除 Doc 实体之前检查这 30 多个引用是正确的。如果这些引用不是来自领域专家的实现细节的结果,那么不,检查这 30 多个引用是不正确的。它们是真正的参考,还是仅仅是设计选择的结果?
在删除任何实体时,可以检查域服务中的交叉聚合条件,如果发现有Related entity导致Doc无法被删除,则报告删除失败。
此验证在服务中的示例实现如下所示:
public void DocDeletion.Delete(Doc doc)
{
var relatedEntities = relatedEntityRepository.FindRelatedEntitiesWithReportDate(doc.ReportDate);
if (relatedEntities.Any())
{
DomainEvents.Raise(new RelatedEntityPreventedDocDeletionEvent(doc, relatedEntities));
}
else
{
// Assumes docRepository.Delete raises relevant domain event
docRepository.Delete(doc);
}
}
我想分享一下我在阅读这个问题时的一些想法,但首先是一些假设:
-
Doc 是聚合根
-
Related entity 是另一个聚合中的实体
-
没有
Doc 实体/聚合,Related entity 就无法存在
那么在我看来,您在Related entity 和Doc 之间有一个隐式引用,即对于每个Related entity.ReportDate,必须存在一个Doc 和一个相等的ReportDate .
我认为这种关系应该更加明确,而是添加对包含 Doc 的聚合根的直接引用(基于我的假设,Doc 实体的聚合根 ID)。这也将允许两个Related entitys 使用相同的ReportDate 引用两个不同的Docs,这可能是您的域中的要求,也可能不是(询问领域专家)。
无论哪种方式,两个聚合之间的隐式引用现在都是显式的,并且 ReportDate 只需要存储在有意义的地方(Doc 或 Related entity),或者仍然在两者上,如果它是域中正确的东西(不过,这可能意味着Doc.ReportDate 不是Related entity.ReportDate,例如Doc.FiledDate 和Related entity.ReportedDate)。
然后,当您希望删除 Doc 实体时,您必须跨多个聚合进行验证。这种类型的验证通常最好放在域服务中,它可以访问包含Doc 实体和Related entity 实体的存储库,并根据是否删除Doc 来决定是否实际删除找到任何相关的Related entitys 限制Doc 被删除(例如,匹配ReportDate 或对聚合根Doc 的引用)。
关于验证/操作结果报告的更多细节,可以找到here。