【问题标题】:Accessing AR from value object从值对象访问 AR
【发布时间】:2026-01-11 00:35:01
【问题描述】:

我有一个很难解决的问题。 在我的模型中,我有AR UnitAR StageVO GoToPositionOrder,它们实现了Order 接口。

它是这样工作的:

  • 我创建订单:order = GoToPositionOrder(Position(Point(3, 4)))
  • 我给单位:unit.followOrder(order)(我可以给单位各种命令)
  • 订单存储在单位中,然后我可以存储单位:unitRepository.store(unit)
  • 存储在unit中的订单每一步都跟着unit,直到订单完成,所以每次发送事件TimeStep,我调用域服务unitsFollowOrders(unitRepository.all())

现在,问题出在哪里?每个命令在遵循时对给定单元(命令模式)执行一些操作:order.execute(unit)。问题是不同的订单需要不同的附加数据来执行其操作。例如GoToPositionOrder 需要访问AR Stage,以便找到最短的定位路径。但是我怎样才能让Order 访问Stage

我不能简单地在那里传递引用,因为出于各种原因,AR 应该由 id 引用。如果它被 id 引用,那么要检索它,VO 将有权访问存储库,这违反了 SRP(单一责任原则)。

我还有什么其他选择?

【问题讨论】:

  • 您似乎正试图以 VO 的形式将命令(如在命令模式中)封装在聚合根中,这很奇怪。我通常会有一个应用程序服务/命令处理程序负责从存储库中获取聚合根并协调对它们的调用,而不是让 Command 对象本身执行此操作,但这可能不是您想要的。
  • 嗯,它来自我的 UL,即“单位有订单”。当然,我可以让VO Order 只是为了定义订单类型,并且基于该类型,我可以在单元上运行应用程序服务。但是我的方法比这种方式更能捕捉我的应用程序行为,因为订单行为保持有序,而不是服务。无论如何,这是否意味着VO不能参考AR?如果可以,那么我们必须使用给定的 VO 加载 AR,并且对于每个找到的 VO,加载他们需要的 AR。好像真的很麻烦。
  • 我刚刚意识到,VO 必须是不可变的,因此它不能引用可变对象,对吧?
  • 我不认为 VO 是协调聚合动作的正确对象。一个 VO 应该引用一个,更不用说多个 AR 了,这似乎很奇怪。您真的需要在 Unit 中保留订单吗?不应该将其建模为命中 AR 的命令序列吗?
  • 是的,你是对的。我应该将多个聚合上的操作提取到域服务中,尽管我牺牲了一些模型清晰度。订单无论如何都需要存储在单元中,因为它们必须在请求之间持久化,它们肯定不是 AR,所以我不能单独持久化它们。

标签: domain-driven-design aggregateroot value-objects


【解决方案1】:

我认为域服务是放置寻路逻辑的正确位置,因为该功能似乎不属于任何实体,是无状态的,并且需要来自多个 AR 的数据。

它将有一个FindShortestPath() 方法产生一个GoToPositionOrder VO,然后将其注入Unit。 VO 将不包含任何逻辑,仅包含 Unit 达到其目标所要采取的步骤列表。

【讨论】: