大家好,关于UML组合与领域驱动设计(DDD)中的聚合关系解析很多朋友都还不太明白,今天小编就来为大家分享关于的知识,希望对各位有所帮助!
意见(太长,无法阅读)
UML聚合描述对象之间的关系,分为两种:一种是共享聚合,也就是我们常说的聚合,另一种是组合聚合,也就是组合。共享聚合通常是一种未经深思熟虑的关系(通常是多对多),这在建模中是一种不好的品味,并且不推荐。 UML聚合是一种技术实现,描述技术解决方案而不是现实世界的关系。 DDD的聚合模式是一种对对象进行分组的方法。 DDD中的聚合是指具有固定规则(业务约束)的对象组。对象组中的对象之间的关系是一种组合。在DDD出现之前,技术人员在实现代码中凭经验区分使用关联和组合,而DDD的聚合模式提供了一种指导业务约束的方式,在这种情况下,通过识别对象之间的固定规则,更适合使用组合。
一个熟悉的概念
说起组合和聚合这两个概念,我最早接触的还是来自采访刻板印象。只记得在网上找到的《Java程序员面试指南》里说,当面试官问你什么是“组合”,什么是“聚合”时,这个时候回答问题的关键点是,同一个生命周期就是组合,不同的生命周期是一个聚合。至于什么是生命周期,最常见的例子就是汽车和轮胎。汽车报废后,轮胎仍然可以安装在其他汽车上,人的大脑随着人的死亡而死亡。听起来颇为浪漫:桃园三个“不求同年同月同日生,但愿同年同月同日死”的结拜伙伴,算作是一个组合。他们彼此有血缘关系,却没有瓦岗一炉香那样的忠诚。它们算作总量。看来聚合本质上是带有贬义的。那么当谈到UML图时,实体图是组合,开放图是聚合。你可以看到,即使是图表也显得不那么慷慨。生命周期已成为采访中的关键词。一旦回答出来,面试官就会假装自己听懂了,面试官也会假装自己听懂了。
[**图**1]_宁学桃源有三结义兄弟,不学瓦岗有一炉香_
DDD的聚合
后来接触了DDD。 DDD中也有聚合,但是很明显DDD聚合和UML聚合不是一回事。从英文单词来看,DDD聚合是aggregate,而UML聚合是aggregation。两者之间存在语义差异:
聚合:指将单独的元素组合在一起形成更复杂的结构。在软件工程中,聚合用于描述一个对象与多个可以独立存在的对象之间的关系。
聚合:指由许多不同元素或部分组成的整体,通常以其大小或复杂性为特征。在软件工程中,聚合用于描述作为一个单元连接在一起的一组对象。
仅从名称来看,两者是有区别的。聚合是一种关系描述,而聚合是一组对象的统称。
DDD中聚合的定义:“在关联复杂的模型中,很难保证对象变化的一致性。不仅不相关的对象需要遵守一些固定的规则(Invariants),而且密切相关的组对象也必须遵守然而,过于谨慎的锁定机制可能会导致多个不变量无意义地相互干扰,从而使系统不可用(因此)我们应该将ENTITY 和VALUE OBJECT 分组到AGGREGATE 中,并定义每个AGGREGATE 的边界。在每个AGGREGATE 中,选择一个ENTITY 作为根并控制对边界内其他对象的所有访问。 可以传递对内部成员的临时引用。由于根控制访问,因此无法修改内部对象,这样的设计有助于确保AGGREGATE 中的对象满足所有固定规则,并且还确保当任何状态发生变化时,AGGREGATE 作为一个整体满足固定规则。” [Eric Evens,领域驱动设计:如何处理软件的核心复杂性]。
看起来DDD的聚合更像是一种一刀切的解决方案(作为一个整体而不是单独处理,总是作为一个组来处理)来管理对象之间的一些固定规则。
DDD实际运行过程中,识别聚合有两个条件:
整体与部分的关系,一个对象是另一个对象的一部分。
物体之间有固定的规则。具体来说,一个对象的属性与另一对象的属性之间存在业务逻辑规则。必须始终维持这一逻辑规则。
DDD聚合和UML聚合
显然UML聚合和DDD聚合不是指同一个概念,对应的词aggrate和aggregation也不同。他们有可能指的是同一件事吗?从简单的生命周期定义中,你会发现不对劲,因为聚合是一组不同生命周期的对象之间的关系,而聚合是一组整体存储和检索的对象。那么,UML的结合和DDD的聚合是同一个概念吗?呢绒?
在DDD原书中,聚合是一种管理对象生命周期的技术。同时,UML组合和聚合的重要区别在于生命周期是否一致,而组合是具有相同生命周期的对象关系,那么DDD聚合中的对象之间的关系是组合吗?
有没有可能DDD的聚合中的对象没有相同的生命周期?例如,聚合根的生命周期已经结束,但聚合中的部分仍然存在。我确实找到了这个例子:
假设有一个在线购物平台,用户可以在其中下订单购买商品。用户在下订单的过程中,可以选择多个产品,每个产品对应一个订单行。然而,有时用户在下订单时可能会犯错误,将某个产品放入错误的订单中。此时,用户希望将该订单行转移到另一个订单,而不是取消整个订单并重新下订单。在此业务场景中,订单行可以转移到另一个订单。这可以通过允许用户在订单详细信息页面中编辑订单行,然后选择将该订单行转移到另一个订单来实现。在进行调拨操作时,需要检查目标订单的库存是否充足,避免库存不足。转账成功后,原订单和目标订单需要进行相应更新,包括重新计算订单总价等。该功能可以提高用户体验,减少误操作带来的不便。还可以提高平台的运营效率,避免重复订单。
首先,由于订单和订单线必须维持固定的价格规则,因此可以使用DDD聚合模式对订单和订单线进行分组,并标识为聚合根。然而,订单行和订单的生命周期似乎并不总是一致的。生命周期的判断标准不太准确。
UML 组合和UML 聚合
这时候我越来越发现组合和聚合的区分似乎有问题,生命周期的概念太模糊了。为此,我决定在UML 中找到聚合和组合的原始定义。
在官方UML 文档中,当一个对象是另一个对象的属性时,就会使用聚合。这时,UML中就会有一个针对这个属性的枚举值AggregationKind来描述两个对象之间的关系。在UML规范中,AggregationKind是一个枚举类型,用于表示聚合关系的类型。它包括三个枚举值:
none:表示不存在聚合关系,两个对象之间不存在整体-部分关系。
共享:表示聚合关系,整体与部分之间的关系是共享的。共享聚合关系表示整体与部分之间的“多对X”(多对多或多对一)关系。部分可以属于多个整体,但整体可以有一个或多个部分。
复合:表示组合关系,整体与部分之间的关系是强耦合的。组合聚合关系是指整体与部分之间存在“一对多”的关系,部分只能属于一个整体。
多对多关系是领域建模的杀手,但在某些地方它们可能是消除系统耦合的关键。多对多关系的出现说明业务没有明确。多对多关系通常隐藏一对多中间模型。这种情况对于共享聚合中的多对一也存在。往往代码中的遍历方向是从少方到多方,而不是从多方到少方,这类似于多对多的情况。就班级和老师而言,一位老师可以教多个班级,一个班级可以有多个老师。这种情况没有区别。这样的建模是无效的。一方面,多对多的关系会让实施和维护变得非常复杂。例子中,班级和老师之间的业务耦合会互相影响。当更新一些与老师无关的班级信息时,是否会影响老师,反之亦然?另一方面,多对多很少能够表达本质的关系,班级和老师的关系分别是授课某个班级的老师和该班级的老师。这是对老师与班级关系更本质的描述。用多对多的方式来表达是很困难的。
因此,基于实际分析的业务本质,我们可以准确地打开多对多、多对一的关系,找出中间关联对象的业务语义,使模型能够更好地表达业务和高内聚性。低耦合。
[**图**2]__组合物被分割成聚合_
显然常规语义下的UML聚合,即共享聚合,不应该出现在建模中,UML**聚合也不应该出现在任何建模图中**。正如Jim Rumbaugh 所说:“将其视为建模安慰剂。” [朗博,UML 参考]
这个时候,生命周期这个词可能已经失去了指导意义。那么什么是组合呢?更精确的定义在《UML和模式应用》 [Craig Larman]和《UML精粹》 [Martion Fowler]中给出,并且该组合满足三个条件:
部件必须同时只属于一个实体。在转移订单的示例中,虽然订单行属于两个订单,但它同时只属于一个订单。
部分不能独立于整体而存在,即在转移订单的示例中,订单行只能属于订单而不能独立于订单而存在。如果业务中有自由订单行,它们就不会成为组合。
删除整体时,当前属于整体的部分会被级联删除。以转储订单为例,删除转储订单时,已转出的订单行不受影响,但未转出的订单行不受影响。需要级联删除。
[**图3**]__生命周期_
显然,不同生命周期的顺序和顺序线仍然是组合关系。
DDD聚合与UML结合
这时候DDD聚合模式和UML组合的关系就应该清楚了。 UML的组合显然满足了DDD中聚合的处理。
在UML广泛使用的RUP的开发过程中,存在两种类型的模型:领域模型和设计模型。 “在UP 中,术语“域模型”是指现实世界概念类的表示,而不是软件对象。该术语不是指用于描述软件类、软件架构域层或负责的软件对象的一组图表。” [Craig Larman,UML 和应用程序模式] 设计模型包括与技术实现高度相关的类图、序列图等。显然,在RUP中,领域模型和设计模型之间可能存在差异。领域模型中的类中可能存在多对多的关系,需要架构师在设计模型中发挥巧思来解决。这时候,到底把类之间的关系设计为关联还是组合,就是一门难以形容的学问。同时,一些次要的架构师如果未能掌握设计多对多关系的技巧,就会随意将它们设计为聚合(即共享聚合)。
【UML组合与领域驱动设计(DDD)中的聚合关系解析】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
这篇文章讲得真好!我对UML和DDD一直感兴趣。
有13位网友表示赞同!
终于有人把这两种东西结合起来了,期待深入了解!
有10位网友表示赞同!
我一直觉得UML组合和DDD聚合很有关联性,需要更清晰的解释。
有5位网友表示赞同!
学习UML的时候经常遇到聚合的概念,这篇文能给我一些启发吗?
有19位网友表示赞同!
DDD和UML是软件开发中必备的东西啊!希望这篇文章能让我学到更多关于组合与聚合的知识。
有10位网友表示赞同!
我之前学习过UML,但对聚合还不太理解,这篇文正好可以帮到我!
有18位网友表示赞同!
软件架构设计的时候经常用到这些概念,希望能更好地掌握它们的关系。
有10位网友表示赞同!
这篇文章应该很有帮助,我一直在想怎么用组合和聚合来构建更清晰的系统模型。
有15位网友表示赞同!
感觉UML组合和DDD聚合是两个不同领域的概念,但确实有一定的交叉性。
有16位网友表示赞同!
期待深入了解这篇关于组合与聚合的文章,学习新的知识!
有15位网友表示赞同!
看了题目感觉很有意思,应该能让我对软件模型的构建有更深刻的理解。
有16位网友表示赞同!
在实际开发项目中,如何运用UML组合和DDD聚合呢?这篇文章也许会有解答。
有9位网友表示赞同!
文章的内容很吸引人,期待深入了解UML组合与DDD聚合之间的关联性。
有12位网友表示赞同!
我对软件设计模式一直很感兴趣,这篇文应该能给我带来新的启发!
有19位网友表示赞同!
想学习如何用UML和DDD来构建更优雅的系统架构,这篇文章可能是解答!
有11位网友表示赞同!
组合与聚合是一个很有意思的概念,期待作者的深入解释。
有14位网友表示赞同!
我一直很喜欢UML,这篇文可能能让我对软件设计有更全面的了解。
有13位网友表示赞同!
这篇文可以帮助我更好地理解Ddd在实际案例中的应用吗?
有19位网友表示赞同!
希望这篇文章能够把复杂的概念解释得通俗易懂!
有18位网友表示赞同!