定义一组集合?

时间:2019-07-15 15:48:10

标签: domain-driven-design

我正在努力定义/定义“一组集合”。聚合应该被认为是独立的并且是孤立的,但是很容易想到更大的一组聚合在一起。但这是陷阱吗?

使用此“集合集合”,可以枚举集合中唯一属性上的集合并为其建立索引,并使其他域规则可以在集合中的所有集合中得到验证。这很诱人,但也感觉有些不对。

另一种方法是完全避免这种想法,并且不允许/定义一组聚合,并且不允许枚举聚合,而仅加载/保存aggregate-id。如果有必要从其他聚合中引用聚合,则可以使用此选项,并通过这样做建立聚合的互连图。

这些方法类似于在磁盘上的文件夹中具有聚合或具有聚合的“互联网”,其中聚合之间的引用定义了较大的聚合集合。无论如何,我真的陷在这个问题上。我从来没有读过任何关于这个的东西,我猜没有人真的那么在乎吗?我不确定我的解释是否很好,但是我的问题是,是否对“集合集合”有任何定义,或者我们是否应该将集合视为完全孤立的/单独存在的集合,并且仅使用唯一的集合ID(UUID )?

例如,集合的集合可以是地下使用的数据库。但是我想知道的是,该数据库是否像DDD中的任何定义中所定义的那样,或者是否应该将一组聚合视为一个互连的图,其中只能使用该图的遍历来枚举所有“关联”聚合。

3 个答案:

答案 0 :(得分:0)

也许您可以找到agg集共有的公分母,并使用它来工作?

一个简化的例子;有一套书籍和一组用户没有什么共同点,只是您想知道什么时候第一次注册?可能的选择是拥有一个FirstRegistration接口,然后您可以选择展开Books / Users或创建一个特定实体。

答案 1 :(得分:0)

  

我正在努力定义/定义“一组集合”。骨料   应该是孤立无援的,但很容易想到   更大的集合在一起。但这是陷阱吗?

我认为您正在苦苦挣扎,因为确实有一组聚合(实例)的想法非常笼统,并且此类事物的使用是上下文相关的和特定于领域的。人们之所以不特别谈论它,是因为当然您可能具有对多个集合进行操作的行为,但是这些行为并没有赋予这些集合任何特定的公共属性或要求,从一般DDD的角度来看,要比“一组集合”,“一组不同的集合”或类似特征更具体地描述此类集合。

  

使用此“集合集合”,例如   枚举和索引集合中唯一属性的集合,并   还有其他可以在所有汇总中验证的域规则   在集合中。这很诱人,但也感觉有些不对。

为什么要诱惑?您已经用非常抽象的方式提出了这个问题,因此就“可能”与您矛盾几乎是不可能的,但是仅仅因为可能存在并不意味着它会有用。 。在实践中,我认为您会发现,对聚合集合进行操作的规则或行为最自然地不属于抽象意义上的聚合集合,而是属于域模型中的其他聚合类型,域存储库或域服务。

您的域模型可能想处理由某些规则表征的特定集合的集合是完全合理的。例如,如果您是航空公司,则域模型中的汇总之一可能是航班上的一个座位,因为这是您出售的单位。在这种情况下,例如在特定航班的所有座位上都会进行操作是有道理的,但是您可能具有的任何规则和行为,都是专门针对特定类型的集合的,以这种特定方式选择。

  

另一种方法是完全避免这种想法,而不是   允许/定义一组集合,而不允许枚举集合   但仅加载/保存聚合ID。

禁止处理集合集肯定会适得其反。只是不要给它带来比保证更重要的意义。总的来说,集合集没有什么特别的地方。

  

如果可能,请使用此选项   引用其他聚合中的聚合所必需   这样就建立了一个相互关联的聚集图。

我不遵循。当然,必须能够从持久性中检索和存储单个聚合,因为这或多或少是聚合的定义属性-它们是持久性的单位。但这并不意味着您必须拒绝使用聚合集合的功能。但是,集合集不像单个集合集那样具有 identity ,因此,是的,集合集之间的关系需要根据单个集合集进行建模。但是,这并不固有地排除聚合之间的1:m或n:m关系。

  

我真的在这个问题上陷入困境。我从没有读过任何有关此的文章,我猜没有人真的很在乎吗?

在基于DDD思想构建和维护的应用程序中,您会发现各种集合的各种用法,但是在您的问题的抽象级别上没有太多要讨论的内容,并且已经总结了什么“设置”和“汇总”一词。

  

例如,聚合集合可以是正在使用的数据库   在表面之下。但是我想知道的是,该数据库是否如   关于其包含的聚合的信息具有任何定义   在DDD中

据我所知。我怀疑大多数DDD从业人员只会将其称为“数据”或类似的东西。

  

或者我们是否应该将一组聚合视为   互连图,其中只能遍历该图   枚举所有“关联”聚合。

我仍然不明白您为什么要设置它。当然,根据域模型的不同,您可能可以通过遍历聚合之间的关联来遍历所有数据或大量数据,这可能适合某些用途,但是DDD不必给出特殊的名称或特殊的规则集合集合供您使用。

与任何有用的方法一样,DDD可以解决问题。它的面包和黄油是复杂的应用程序,具有复杂的数据和不断变化的要求。不应将其解释为是一件直截了当的事情,它阻止设计人员和开发人员(经过深思熟虑)编写包含其他设计方法各个方面的设计和代码,更不用说满足应用程序特殊需求的设计和代码了。

答案 2 :(得分:0)

聚合已连接

在任何具有足够复杂性的应用程序中,聚合最终都会引用另一个。并且使用它们的唯一标识符作为参考ID相互参考是完全合理的。

但是要小心,要在域层外部(通常是在存储库中)加载和持久保留聚合。如果要遍历聚合中的链接并将其加载到内存中,则需要先进行该操作,然后再将控制权移交给域层进行实际处理。

遍历图以获取所有相关的聚合是正确的,但这很少跨越太多的聚合边界。您很少会发现要在整个应用程序中应用的单个更改或规则。如果您确实有这样的交易,那可能是域设计需要改进的标志,仅仅是因为您正在众多聚合中分散一项职责/变更。

连接是如此常见,因此您应注意与系统其余部分没有链接的聚合。它们要么是独立的库,要么可能属于不同的有界上下文。

聚集体可以变形为不同形式

它们是集合体,因为它们形成了清晰的不变边界,其主要职责是对自身内部的所有实体在状态变化中强制不变。但是它们可以根据需要变形为不同种类的DDD对象。

一个很好的例子是一个单一的纸币。在大多数应用程序中,它们是价值对象。但是对于联邦银行来说,它们是具有明确不变规则的集合。它们在创建和引用时是聚合的,但是在将打印的票据运送到银行的交易中,它们可能成为价值对象。

因此,当您考虑每个链接时,您可能必须评估是以域的聚合形式还是以值对象的形式谈论域实体。

聚合是不变的边界

验证跨集合的域规则是错误的。

您的集合边界是一个不变边界,这意味着其中的所有域规则都应始终得到满足。按照这种逻辑,您将错误地构建一个结构,该结构将需要确保聚合中的所有域规则始终有效。这样做会带来相当大的性能负担,更不用说业务逻辑的复杂性了。

但这并不是说可能存在跨聚合的域规则。要做到这一点,正确的方法是使用最终一致性和事件驱动的方法。

主要的变化汇总将验证并保留数据,并冒泡一个包含状态变化的事件。然后,其他聚合将对该事件起作用并使其保持最新状态。如果聚合的域规则由于更改而中断,通常会使用一种补充机制,该机制可以纠正问题(首选机制)或回滚第一个状态更改(很少发生)。