美文网首页
DDD碎片记录 08. 聚合是什么

DDD碎片记录 08. 聚合是什么

作者: 黑铁大魔王 | 来源:发表于2022-04-30 09:34 被阅读0次

将领域模型最终转设计,可以落实到三种类型的对象设计,

  1. 服务,2. 实体,3. 值对象,

然后进行贫血模型与充血模型的设计思路。
除此之外还需要有聚合,仓库,工厂的设计。

聚合:是领域驱动设计中一项非常重要的设计与概念,它表达的是真实世界中那些整体与部分的关系。

比如订单与订单明细表单与表单明细、发票与发票明细。

以订单为例,在真实世界中,订单与订单明细本来是同一个事物,订单明细是订单中的一个属性。但是,由于在关系型数据库中,没有办法在一个字段中表达一对多的关系,因此必须将订单明细设。
在领域模型的设计中,我们又将其还原到真实世界,以聚合的形式进行设计。
在领域模型中,即将订单明细设计成订单中的一个属性。
有了这样的设计,订单的时候将不再单独,而是将订单明细创建在订单中。
订单的时候应当同时保存订单表与订单明细表,并放在同一事务中。
查询订单时,应当同时查询订单表与订单明细表,并将其装配成一个订单对象,这时候订单就作为一个整体进行操作,而不需要再单独去操作订单明细。
也就是说,对订单明细的操作是封装在订单对象内部的设计实现。
对于客户程序来说去使用订单对象就好了。
这就包括了作为属性去访问订单对象中的订单明细,而不再需要关注它内部是如何操作的。
按照以上思路进行的设计就是聚合
当创建或更新订单时,在订单对象中填入或更新订单的明细就好了。
当保存订单时,只需要将订单对象作为整体去保存,而不需要关心订单数据是怎么保存,保存到哪几张表中,是不是有事物。保存数据库的所有细节都封装在了订单对象内部。
当删除订单时,删除订单对象就好了,至于如何删除订单名细是订单对象内部的,实现,外部的程序不需要关注。
当查询或装载订单时,客户程序只需要根据查询语句或id查询订单对象就好了。查询程序会在查询过程中自动的去补填订单对应的订单明细。

聚合体现的是一种整体与部分的关系。

正是因为有这样的关系,在操作整体的时候,整体就封装了对部分的操作,但并非所有对象间的关系都有整体与部分的关系。而那些不是整体与部分的关系是不能设计成聚合的。
因此,正确的识别聚合关系就变得尤为重要。
所谓的整体与部分的关系就是当整体不存在时,部分就变得没有了意义。
部分是整体的一个部分,与整体有相同的生命周期。

比如只有创建了这张订单,才能创建它的订单明细,如果没有了这张订单,那么它的订单明细就变得没有意义,就需要同时删除掉。
这样的关系才具备整体与部分的关系,才是聚合。
比如订单与用户之间的关系就不是聚合,因为用户不是创建订单时才存在的,而是在创建订单时早就存在了。
当删除订单时,用户不会随着订单的删除而删除,因为删除了订单,用户依然还是那个用户。
那么饭店和菜单的关系是不是聚合关系呢?
这就要看系统如何设计了。如果系统设计成每个饭店都有各不相同的菜单,每个菜单都是隶属于某个饭店,则饭店和菜单是聚合关系。
让各个饭店都有宫保鸡丁,但每个饭店都是各自不同的宫保鸡丁。
比如在描述图片或价格上的不同,甚至在数据库中也是有各不相同的记录。
这时要查询菜单就要先查询饭店,离开了饭店的菜单是没有意义的。
但是饭店和菜单还可以有另一种设计思路,就是所有的菜,菜单都是公用的。
去每个饭店只是选择有还是没有这个菜品,这时系统中有一个菜单对象,宫保鸡丁只是这个对象中的一条记录,其他各个饭店,如果他们的菜单上有宫保鸡丁,则去引用这个对象,否则不引用,这是菜单就不再是饭店的一个部分。没有这个饭店,这个菜品依然存在,就不再是聚合关系。
因此,判断聚合关系最有效的方法就是去探讨如果整体不存在时,部分是否存在,如果不存在就是聚合。反之,则不是。
有了聚合关系,部分就会被封装在整体里面。
这时就会形成一种约束,即外部程序不能跳过整体。
需要通过整体,整体就下一步唯一入口,被称为聚合根。
也就是说一旦将对象间的关系设计成了聚合,那么外部程序只能访问聚合根,而不能访问聚合中的其他对象。
这样带来的好处就是当聚合内部的业务逻辑发生变更时,只与聚合内部有关,只需要对聚合内部进行更新,与外部程序无关。
从而有效降低了变更的维护成本,提高了系统的设计质量。

需要注意的是,这样的设计并非任何情况下都有效。
比如,在管理订单中,对订单进行增删改时,聚合是有效的。
但是如果要统计销量、分析销售趋势、销售占比时,则需要对大量的订单明细进行汇总进行统计。如果每次对订单明细的汇总与统计都必须经过订单的查询,必然使得查询统计变得效率极低而无法使用。

因此领域驱动设计通常适用于增删改的业务操作,不适用于分析统计。
在一个系统中,增删改的业务可以采用领域驱动设计,但在非增删改的汇总,分析场景中则不必采用领域驱动的设计。直接sql查询就好了,也就不必再遵循聚合的约束。

相关文章

  • DDD碎片记录 08. 聚合是什么

    将领域模型最终转设计,可以落实到三种类型的对象设计, 服务,2. 实体,3. 值对象, 然后进行贫血模型与充血模型...

  • ddd

    DDD理解:基本概念:DDD战略思想:领域、子领域、限界上下文、通用语言、下文映射图、架构风格DDD战术实现:聚合...

  • 多研究些架构,少谈些框架(2):微服务和充血模型

    上篇我们聊了微服务的DDD之间的关系,很多人还是觉得很虚幻,DDD那么复杂的理论,聚合根、值对象、事件溯源,到底我...

  • 窗口函数总结

    一、窗口函数是什么 窗口函数不会进行聚合,将多条记录按照分组字段聚合成一条记录。而是通过移动窗口,对每一条记录进行...

  • DDD之4聚合和聚合根

    聚合就是归类的意思,把同类事物统一处理;聚合根也就是最抽象,最普遍的特性; 背景 领域建模的过程回顾: 那么问题来...

  • DDD落地需要考虑的问题

    DDD的核心思想封装,从业务角度进行领域的划分、聚合的隔离,即业务的封装,聚合是业务的最小单元,具有原子性特征,聚...

  • DDD中的聚合根

      最近在看一本书,看到了AGGREGATE(聚合),AGGREGATE root(聚合根)。下面解释下这两个的意...

  • DDD碎片记录 09. 仓库和工厂

    上一篇说的聚合,通过聚合设计可以真实的反应现实世界的状况,提高软件设计的质量,有效降低维护变更的成本。 仓库+工厂...

  • 大话DDD — 聚合、仓库与工厂

    DDD中的工厂和设计模式中的工厂不是同一个概念 聚合 聚合表达的是真实世界中整体和部分的关系,例如订单与订单明细。...

  • 领域驱动设计DDD入门(一)

    领域驱动设计简介 领域驱动设计(Domain-Driven Design)简称DDD。 目录 DDD是什么? DD...

网友评论

      本文标题:DDD碎片记录 08. 聚合是什么

      本文链接:https://www.haomeiwen.com/subject/lvuwsrtx.html