同一聚合中的依赖实体

Dependent entities within same aggregate

情况:

我们有经典的 OrderOrderLine。每个 OrderLine 都引用了 ProductId.

每个 Product 都有其 RelatedProduct。例如,产品

class Product {
   string Id;
   string Name;
   string RelatedProductId;
   decimal RelatedProductQuantity;
   .
   .
   .
}

有一条业务规则,每当将 Product 添加到 Order 和新的 OrderLine 时,也应将 Productid=RelatedProductId 添加到quantity=RelatedProductQuantity.

问题:

  1. 如何将此规则保留在域中,使其不会溢出到应用程序服务,但同时在某种意义上保持 Order 聚合清洁,以免通过注入毒化它存储库或任何数据获取的东西?

  2. 我们应该使用域服务吗?如果是这样,域服务是否可以注入存储库、准备所有数据、创建 OrderLine(对于基础产品和相关产品)、填写聚合并将其保存到存储库?

  3. 如果 none 以上,最好的建模方法是什么?

您将在此处看到两种常见模式:

  • 获取应用程序代码中信息的副本,然后将该信息作为参数传递给域模型
  • 将获取信息的能力作为参数传递给域模型

第二个选项是经典的“域服务”方法,使用“无状态”实例来获取“全局”状态的副本。

但是,从正确的角度来看,您可能会认识到第一种方法是相同的机制 - 只是它是应用程序代码,而不是域代码,它获取信息的副本。

在这两种情况下,决定如何处理信息副本的仍然是域模型,所以没关系


可能的决胜局:

如果您需要复制的信息不是本地的(即:您正在处理一个分布式系统,并且该信息在本地缓存中不可用),那么获取该信息将有失败模式,并且您可能不想用一堆代码来处理该问题(就像您不想用一堆与数据库相关的问题污染您的域代码一样)。

如果很难提前猜测将传递哪些 参数 来获取数据,那么让域代码直接调用该函数可能是有意义的。否则,您最终会得到应用程序代码向域模型询问参数,并将信息传递回模型,这甚至可能来回乒乓几次。

(并不是说它不能完成:你可以让它工作 - 不太清楚的是你将如何快乐地维护代码)。

如果您不确定...请使用感觉更熟悉的方法。