聚合、组合和依赖之间有什么区别?

274

聚合、组合和依赖关系有什么区别?


3
重新开放:重复链接并不是完全相同的问题(依赖关系 vs 关联性)。此外,这个问题具有同样的相关性。 - Adrian Maire
7个回答

445

聚合 意味着一种父子关系,其中子级可以独立于父级存在。例如:班级(父级)和学生(子级)。删除班级后,学生仍然存在。

组合 意味着子级不能独立于父级存在。例如:房屋(父级)和房间(子级)。房间不存在于房屋之外。

以上两种属于包含关系(因此是父子关系)。

依赖关系 是一种较弱的关系,代码术语中表示一个类通过参数或返回类型使用另一个类。

依赖是一种关联关系


1
不是说你对错与否,但这些分类真的很糟糕。班级/学生==聚合吗?... 但JavaPapers.com并不这样认为。http://javapapers.com/oops/association-aggregation-composition-abstraction-generalization-realization-dependency/ "一个班级包含学生。没有班级就不存在学生。班级和学生之间存在组合关系." - TallPaul
20
@tallPaul,你提到的那篇论文支持我的聚合和组合定义。它只是对“学生”的定义有所不同。它说,没有班级就没有学生。如果是这样,那么就是组合。如果不是,那就是聚合。我不喜欢他们的前提:学生可以存在而不在任何班级中。 - cletus
1
你可能随后会转到另一个班级 :-) 还有很多学生实际上并没有在学习... - scravy
6
这不是绝对的,它取决于业务;如果你正在设计一些CAD软件,并且倾向于在屏幕上添加物体(厨房、浴室),那么可以没有建筑而存在空间... 在器官移植行业中,身体部位并不一定是组成部分。这就是为什么你必须描述清楚你真正想要的。 - Peter
2
这完全取决于你的抽象限制。无论你将一个实体视为仅在课堂上的学生还是在课堂外也是如此。 - Rahul Rastogi
显示剩余5条评论

147

聚合组合基本上完全相同,唯一的区别是当子元素的生命周期完全受父元素控制时,使用组合

聚合

Car -> Tires
Tires可以从Car对象上拆下来并安装在另一个车上。此外,如果汽车被撞毁,轮胎不一定要被销毁。

组合

Body -> Blood Cell
Body对象被销毁时,BloodCells也会随之销毁。 依赖关系 两个对象之间的关系,更改其中一个可能会影响另一个。

14
有趣的是,我刚看过一篇教程,在其中使用汽车轮胎的例子来说明组合的概念。 - mouviciel
12
有趣,我想这取决于你如何看待它。我不明白摧毁汽车物体也必须摧毁轮胎的逻辑。此外,您可以将轮胎从一辆车上卸下并安装到另一辆车上。但我想这就是比喻的问题吧。 - Robert Greiner
5
有趣,我猜这取决于你如何看待它。我喜欢这个回答,但你知道现在我很困惑。 - Kowser
15
在这里,关键是要有透视。例如,罗伯特似乎不知道献血的做法,或者他可能是一名见证人 - 因此他得到了组合。我会选择聚合。这很好地说明这些事情不是关于绝对真理,而是关于 模型:如果在您的世界/应用程序中,轮胎属于唯一的一辆汽车,并且您将它们与汽车一起摧毁,请使用组合;如果您在汽车之间切换它们,请使用聚合。 - Raphael
3
太多的评论者被实例所困扰。每个实例描述的句子似乎都很好。在一个设计中,也许摧毁一辆车会破坏轮胎。在别人的设计中,轮胎可以被拆下来并回收利用。这个细节是不相关的。关键是基础事物(孩子)是否与父对象具有相同的生命周期。如果生命周期紧密耦合,那么它就是组合关系。答案是正确的。在特定的程序中,将血细胞转移到另一个身体可能是不必要的。这取决于程序的要求。 - shawn1874
显示剩余3条评论

50

聚合 - 由不同部分组成的整体,每个部分都有自己的身份,独立于其所属的整体。您可以选择该部分并将其移动到另一个对象中。(现实世界的例子:轮子->汽车,血细胞->身体)

组合 - 整体不可分割的部分。您无法将此部分移动到另一个对象中,更像一种属性。(现实世界的例子:曲线->道路,个性->人物,最大速度->汽车,对象的属性->对象)

请注意,一个在一个设计中是聚合关系,在另一个设计中可能是组合关系。这完全取决于特定设计中如何使用关系。

依赖 - 容易受到变化的影响。(雨量->天气,头部位置->身体姿势)

注:“Bloodcell”->“Blood” 可以被视为“组合”,因为没有名为“血液”的实体,血细胞无法存在。“Blood”->“Body”可能是“聚合”,因为血液可以存在而无需名为“身体”的实体。


7

组合关系相关联的对象将不会存在于包含对象之外。例如,预约和所有者(人员)或日历;测试结果和患者。

另一方面,被包含对象聚合在包含对象中,但可以存在于该包含对象之外。例如,门和房屋;员工和部门。

依赖关系涉及到协作或委托,其中一个对象请求另一个对象的服务,并因此依赖于该对象。作为服务的客户端,您希望服务接口保持不变,即使未来提供了其他服务。


5
聚合和组合是大多数面向对象世界中通过UML获得的术语。而UML在定义这些术语方面做得非常糟糕,例如Henderson-Sellers和Barbier在《聚合是什么?》和《统一建模语言中整体-部分关系的形式化》中已经证明过。如果您希望符合UML标准,我认为聚合和组合的一个连贯的定义是无法给出的。建议您查看引用的作品。
关于依赖性,它是类型(而不是对象)之间的高度抽象关系,可以表示几乎任何内容。

1

一个对象可能作为其属性的一部分包含另一个对象。

  1. 文档包含包含单词的句子。
  2. 计算机系统具有硬盘、内存、处理器等。

因此,包含关系不一定是物理上的。例如,计算机系统有保修。


0

包含:- 在这里,我们必须使用外部对象才能访问内部对象。我们可以重复使用所包含的对象。 聚合:- 在这里,我们可以无需使用外部对象多次访问内部对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接