Domain driven design 同一聚合中的从属实体

Domain driven design 同一聚合中的从属实体,domain-driven-design,Domain Driven Design,情况: 我们有一个经典的Order,带有OrderLines。每个OrderLine都引用了ProductId 每个产品都有其相关产品。例如,产品 class Product { string Id; string Name; string RelatedProductId; decimal RelatedProductQuantity; . . . } 有一条业务规则,每当使用新的OrderLine将Product添加到Order中时,那么使用id=

情况:

我们有一个经典的
Order
,带有
OrderLine
s。每个
OrderLine
都引用了
ProductId

每个
产品
都有其
相关产品
。例如,产品

class Product {
   string Id;
   string Name;
   string RelatedProductId;
   decimal RelatedProductQuantity;
   .
   .
   .
}
有一条业务规则,每当使用新的
OrderLine
Product
添加到
Order
中时,那么使用
id=RelatedProductId
Product
也应添加到
quantity=RelatedProductQuantity

问题:

  • 如何在域内保持此规则,使其不会溢出到应用程序服务,但同时保持
    顺序
    聚合干净,从某种意义上讲,不通过注入存储库或任何数据获取东西毒害它

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

  • 如果以上都没有,那么最好的建模方法是什么


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

    • 获取应用程序代码中信息的副本,然后将该信息作为参数传递给域模型
    • 将获取信息的功能作为参数传递给域模型
    第二个选项是经典的“域服务”方法,其中使用“无状态”实例获取“全局”状态的副本

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

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


    可能的联络断路器:

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

    当很难预先猜测将要传递哪些参数来获取数据时,让域代码直接调用该函数可能是有意义的。否则,应用程序代码最终会向域模型询问参数,并将信息传递回模型,这甚至可能是乒乓球来回几次

    (并不是说它做不到:你可以让它工作——更不清楚的是你对维护代码有多高兴)

    如果您不确定……请使用更熟悉的方法