【发布时间】:2026-01-11 00:35:01
【问题描述】:
我有一个很难解决的问题。
在我的模型中,我有AR Unit、AR Stage 和VO 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