【发布时间】:2015-05-27 09:08:37
【问题描述】:
我们想要为仓库应用程序建模。让我们假设我们确定了以下现实世界的对象:
- 物品(仓库存放的东西)
- 调色板(文章所在的位置)
- 隔间(货架上存放调色板的地方)
有以下限制:
- 调色板恰好在一个隔间中
- 一个隔间可以容纳零个或一个调色板
首先我们有一个操作:
- 移动(将调色板从其当前隔间移动到另一个隔间)。
当然这是非常简化的。
这应该如何建模?
我认为 Stockitem 可能是一个价值对象。一种解决方案是将整个仓库建模为具有调色板和隔间实体的聚合体。在这种情况下,关于其约束(不变量),可以毫无问题地实现移动操作。但是这种方法有明显的缺点。此聚合的事件日志将无限增长。由于聚合版本控制等原因,两个移动操作无法并行执行。而且从 ddd 的角度来看,这对我来说感觉不合适。
另一种方法是让每个调色板和每个隔间都有自己的聚合。但是那移动操作怎么实现呢?
问题 1:谁加载引用的聚合?
我认为它应该坚持使用调色板。调色板可以引用它所在的隔间(它是一个聚合)。但是这个参考是如何实现的(CQRS/ES)? move 命令的 Comandhandler 显然将从调色板存储库加载调色板聚合并在其上调用 move 方法。谁加载引用的隔间?谁来装载它应该移动到的隔间?我读到聚合不应该访问存储库。指挥员应该装载两个隔间吗?隔间是否应该作为参数提供给 move 方法?或者命令处理程序是否应该将当前隔间设置为调色板并将目标隔间作为参数?
问题 2 和 3:聚合之间的约束和双向关联
约束呢?要检查目标隔间是否为空,隔间需要知道存储在其中的调色板。这将是应避免的双向关联。并且因为它们是不同的聚合,它们不能在同一个事务中更新。调色板是否有触发域事件以通知隔间它将移动到它?它是否要作为具有撤消操作的 saga 来实现?如果两招冲突,一招胜出,输掉的棋盘却无法挽回,因为此时旧车厢已满?
对于这个非常简单的问题,这一切对我来说似乎都很复杂。
在书籍和示例中,一切似乎都如此清晰。但是如果我尝试使用它,我似乎做错了。
有人可以指导我正确的方向吗?
【问题讨论】:
标签: domain-driven-design cqrs event-sourcing