域驱动设计中的聚合建模

问题描述 投票:0回答:1

此问题与领域驱动的设计及其相关概念有关。

在此示例中,该软件负责管理一组公交路线。公交路线是指公交到达和离开的车站的集合。时间表表示任何路线的偏离以及指定的实际到达和离开时间(同一路线的不同偏离的偏移量可能不同)。库存通过单独的一组表进行管理,这些表定义了任何给定时间表的物理容量及其座位分配。这次旅行是按照特定的时间表从一个车站到另一个车站的预订。

Database Model

在我所附的图中,有多个表簇。每个集群都应该是一个聚合,其根从左开始-

  • Station
  • 有许多路线停靠点的路线
  • 有很多停靠点的时间表
  • 具有许多座位分配/预订的清单
  • 旅行

[在传统架构中(缺少领域驱动的设计及其集合的概念),我会修改设计以强制执行其他自然约束。

例如,座位预订是指出发和到达的站点,以防止从出发站到到达站点的座位预定也不是该时间表的站点。我之所以选择不这样做,是因为据我所知,域驱动的设计不鼓励跨集合引用非根实体。由于schedule是聚合根,因此不包括对调度停止的任何引用。存在相同的情况以确保计划的停靠站实际上是路线停靠站(尽管公平地说,当前设计允许对单个计划的停靠站进行临时调整)。

库存和座位预订已从计划汇总中分离出来,以避免需要跨行程和计划汇总进行交易。通过将容量和座位预订组合在一起,我可以保持不变,即售出的座位数始终小于或等于可用性(客户要求)。在当前的方法中,将在确认行程和处理付款之前确保预订。但是,这种方法仍然使我从旅行汇总到座位预定(这是一个非根实体)的参考。在这种情况下,清单实体是根目录,因为管理员可以随时修改容量以减少或增加可用性。

简而言之,我不相信我完全了解如何定义聚合边界(也许这些聚合太小了)。我一直在抵制将多个聚合合并为一个较大的聚合的冲动,以便数据库可以帮助保持一致性并防止数据损坏。同时,在创建较小的聚合时,我经常很想创建对非根实体的引用。任何解决这些问题的建议将不胜感激!

database-design domain-driven-design cqrs event-sourcing aggregateroot
1个回答
0
投票

很难提供详细信息,因为我没有与域专家联系的机会。但是,关于您的方法的一些事情似乎并不正确。

  1. 如果您专注于域驱动的设计,那么您实际上应该忽略数据库结构。在那个阶段与解决问题无关。如果有的话,以表的方式思考会使您感到困惑,并导致更多的数据优先设计而不是域优先设计。考虑功能。代码需要做什么。而不是数据。

  2. 考虑某些动作(命令)的约束可能会有所帮助。这些应该组合在一起。即集合应该具有维护操作的内部约束所需的全部内容。这种方法可以帮助您找到聚合的边缘。要考虑的其他因素是普遍使用的语言。即确保术语含义相同。这都是找到边缘的好方法。还有更多要查找的集合,但这将使您入门。

希望有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.