Domain driven design DDD-只读的聚合

Domain driven design DDD-只读的聚合,domain-driven-design,aggregateroot,cqrs,Domain Driven Design,Aggregateroot,Cqrs,如果我们正在处理一个子域,其中我们只处理只读场景,这意味着我们的实体和值对象将不会更改,那么创建由根及其子项组成的聚合是有意义的还是应该将此上下文的每个实体映射到单个聚合 假设我们有实体A和实体B 在进行修改的上下文中,我们创建一个由实体a和实体B组成的aggregate,其中a是聚合根(假设B离不开a,其中涉及一些不变量) 如果我们将相同的实体移动到一个不同的环境中,而不进行任何修改,那么保持这个聚合是否有意义,或者我们是否应该为实体a创建一个聚合,为实体B创建一个不同的聚合?在2019年,这

如果我们正在处理一个子域,其中我们只处理只读场景,这意味着我们的
实体和
值对象将不会更改,那么创建由根及其子项组成的
聚合是有意义的还是应该将此上下文的每个实体映射到单个
聚合

假设我们有实体
A
和实体
B

在进行修改的上下文中,我们创建一个由实体
a
和实体
B
组成的
aggregate
,其中
a
聚合根(假设
B
离不开
a
,其中涉及一些不变量)


如果我们将相同的实体移动到一个不同的环境中,而不进行任何修改,那么保持这个
聚合
是否有意义,或者我们是否应该为实体
a
创建一个
聚合
,为实体
B
创建一个不同的聚合?

在2019年,这一想法得到了相当大的支持,即在只读场景中,您根本不需要考虑域模型

只要将数据直接加载到支持用例的只读数据结构中即可


另请参见:。

第一件事是,如果B不能离开A生存,并且涉及到一些不变量,那么对我来说,A是一个聚合根,而B是属于它的实体

聚合根代表了一个真实世界的概念,它的存在不仅仅是为了便于修改。在我们的许多应用程序中,一旦创建了聚合根,我们就不会修改聚合根的状态,也就是说,实际上我们拥有不可变的聚合根。这些方法对于契约式设计检查/不变检查等具有一定的逻辑性,但实际上它们是贫乏的,因为由于其不变性,没有“更新”方法。自从Eric Evans撰写《蓝皮书》以来,很多事情都发生了变化,例如NoSql数据库的概念变得非常流行,函数式编程概念变得非常有影响力,并被推荐使用更先进的DDD风格的体系结构,如CQR。例如,我可以附加(即插入)数据库,而不是对数据库进行更新。这导致聚合不再需要“更新”。这会导致贫血症类型的减少,但这正是我们在这方面想要的。贫血类型之前的问题是,给定类型的“更新逻辑”放在代码库的其他地方,而不是放在类型本身中。然而,如果你不需要“更新逻辑”放在首位,那么你没有这个问题

例如,如果有一个包含许多OrderItems的订单,我们将创建订单聚合根和OrderItem实体。提取域以正确识别聚合、实体和值类型是一个非常重要的概念

然后,域服务、存储库等的创建自然地进行。例如,聚合根和存储库是1对1,即在上面的示例中,我们将有一个Order存储库,而没有OrderItem存储库。这样,您的主要领域概念就会以一种可预测且易于理解的方式散布在您的代码中

最后,在你的具体问题中,我不会将它们视为相同的实体。在一种情况下,您似乎需要修改逻辑——在另一种情况下,您不需要修改逻辑——它们对我来说是独立的领域概念

  • 在进行修改的上下文中:A=agg root,B=entity
  • 在没有修改的上下文中:A=agg root(不可变),B=entity(不可变)

这些数据结构可以用行为填充,还是仍然是贫血模型?它们可以封装一些可用于我们试图解决的用例的行为,这意味着它们仍然被视为“域模型”,即使我们没有应用聚合的概念。我的想法正确吗?请注意,我不是说我们正在加载一些数据以直接发送给客户,我是在考虑一个业务用例,我们仍然需要应用一些逻辑。@PedroFaustino:没有什么可以阻止您向模型添加逻辑,只要模型的所有字段都是只读/最终的,它没有setter或可变类型,所有输入验证都发生在构造函数中(因为这是创建此对象的唯一方法)。这不是严格意义上的DDD(在这种情况下,您不需要应用DDD)很好的解释,谢谢。关于聚合根及其子级,我仍然有一个问题:如果我们不需要加载聚合的所有子级(我们可能只需要使用一个特定的子集),我们是否应该将其拆分为两个聚合?我正在考虑安排一个约会的上下文,在这里我们可以有一个人(root)及其日程表(实体),但我们只需要从今天开始加载日程表。我们如何处理这个问题?顺便说一句,如果我们只需要从数据库加载一些数据来显示给用户(想象一个带有值的查找),我们是否应该跳转DDD部分,直接使用查询对象+DTO来直奔主题?关于第一条注释,我将有两个聚合,因为它们在功能上是不同的。我会将这两个聚合命名为反映它们与第二条注释的功能差异的东西,如果您的代码真的很简单的话,请完全跳过DDD。DDD有它的位置,它永远不应该是过度设计项目的原因,但如果我们创建两个不同的聚合,一个用于个人实体,另一个用于计划实体,我们如何确保个人聚合上的不变量,例如一个人不能同时有两个计划?