关联、聚合和组合之间的区别是什么? 请从实施的角度加以说明。
当前回答
我想这个链接可以帮到你:http://ootips.org/uml-hasa.html
为了理解这些术语,我记得我早期编程时的一个例子:
如果你有一个" chess board "对象它包含" box "对象那就是组合因为如果" chess board "被删除了盒子就没有理由再存在了。
如果你有一个'square'对象,它有一个'color'对象,正方形被删除了,'color'对象可能仍然存在,这就是聚合
它们都是关联,主要的区别是概念上的
其他回答
对于Foo和Bar这两个对象,可以定义关系
关联——我与一个对象有一种关系。Foo使用Bar
public class Foo {
private Bar bar;
};
注意:请参阅Fowler的定义-关键是Bar在语义上与Foo相关,而不仅仅是一个依赖项(如int或字符串)。
组合——我拥有一个对象,我对它的生命周期负责。当Foo死了,Bar也死了
public class Foo {
private Bar bar = new Bar();
}
聚合——我有一个从别人那里借来的对象。当Foo死了,Bar可以活下去。
public class Foo {
private Bar bar;
Foo(Bar bar) {
this.bar = bar;
}
}
摘自Robert Martin在comp.object中的一篇文章:
关联表示一个实例向另一个实例发送消息的能力。这通常是通过指针或引用实例变量实现的,尽管它也可以实现为一个方法参数,或创建一个局部变量。
//[Example:]
//|A|----------->|B|
class A
{
private:
B* itsB;
};
聚合[…是典型的整体/部分关系。这与实例不能具有循环聚合关系(即部分不能包含其整体)的异常关联完全相同。
//[Example:]
//|Node|<>-------->|Node|
class Node
{
private:
vector<Node*> itsNodes;
};
这是聚合的事实意味着Node的实例不能形成一个循环。因此,这是一个节点树,而不是节点图。
成分[…和聚合完全一样,只是“部分”的生命周期由“整体”控制。这种控制可以是直接的,也可以是传递的。也就是说,“整体”可以直接负责创造或破坏“部分”,或者它可以接受一个已经创建的部分,然后将它传递给其他某个整体,由其承担责任。
//[Example:]
//|Car|<#>-------->|Carburetor|
class Car
{
public:
virtual ~Car() {delete itsCarb;}
private:
Carburetor* itsCarb
};
协会
关联表示两个类之间的关系。它可以是单向的(单向)或双向的(双向)
例如:
单向
客户下单
双向
A和B结婚了 B和A结婚了
聚合
聚合是一种关联。但是有特定的特征。聚合是一个较大的“整体”类包含一个或多个较小的“部分”类之间的关系。相反,一个较小的“部分”类是“整个”较大类的一部分。
例如:
俱乐部有会员
一个俱乐部(“整体”)是由几个俱乐部成员(“部分”)组成的。会员可以在俱乐部外生活。如果俱乐部(“整体”)死亡,成员(“部分”)不会随之死亡。因为会员可以属于多个俱乐部(“整体”)。
作文
这是一种更强的聚合形式。“整体”对其“部分”的创造或破坏负责
例如:
学校有院系
在这种情况下,学校(“整体”)将消亡,部门(“部分”)将随之消亡。 因为每个部分只能属于一个“整体”。
摘自:Remo H. Jansen的《Beginning React: Learning TypeScript 2》。x -第二版”:
We call association those relationships whose objects have an independent life cycle where there is no ownership of the objects. Let's take a look at an example of a teacher and a student. Multiple students can be associated with a single teacher, and a single student can be associated with multiple teachers, but both have independent life cycles (both can create and delete independently). So, when a teacher leaves the school, we don't need to delete any students, and when a student leaves the school, we don't need to delete any teachers.
我们称这些关系为聚合,其对象具有独立的生命周期,但存在所有权,并且子对象不能属于另一个父对象。让我们以手机和电池为例。单个电池可以属于一个手机,但如果手机停止工作,我们从数据库中删除它,手机电池将不会被删除,因为它可能仍在工作。因此,在聚合中,虽然有所有权,但对象有它们的生命周期
我们使用术语组合来指代对象没有独立生命周期的关系,如果父对象被删除,所有子对象也将被删除。让我们以问题和答案之间的关系为例。一个问题可以有多个答案,答案不能属于多个问题。如果我们删除问题,答案将自动删除。
令人惊讶的是,关于关联、聚合和组合这三个关系概念之间的区别存在如此多的混淆。
请注意,术语聚合和组合已经在c++社区中使用,可能在它们被定义为UML类图中关联的特殊情况之前已经有一段时间了。
主要的问题是广泛的和持续的误解(甚至在专家软件开发人员中),组合的概念意味着整体和它的部分之间的生命周期依赖关系,以至于部分不能没有整体而存在,忽略了这样一个事实,即也存在与不可共享部分的部分-整体-关联的情况,其中部分可以从整体中分离出来,并且在整体被破坏后仍然存在。
在我看来,这种困惑有两个根源:
In the C++ community, the term "aggregation" was used in the sense of a class defining an attribute for referencing objects of another independent class (see, e.g., [1]), which is the sense of association in UML Class Diagrams. The term "composition" was used for classes that define component objects for their objects, such that on destruction of the composite object, these component objects are being destroyed as well. In UML Class Diagrams, both "aggregation" and "composition" have been defined as special cases of associations representing part-whole relationships (which have been discussed in philosophy for a long time). In their definitions, the distinction between an "aggregation" and a "composition" is based on the fact if it allows sharing a part between two or more wholes. They define "compositions" as having non-shareable (exclusive) parts, while "aggregations" may share their parts. In addition they say something like the following: very often, but not in all cases, compositions come with a life-cycle dependency between the whole and its parts such that the parts cannot exist without the whole.
因此,尽管UML将术语“聚合”和“组合”放在了正确的上下文中(部分-整体关系),但是他们并没有设法以一种清晰和明确的方式来定义它们,从而捕捉开发人员的直觉。然而,这并不奇怪,因为这些关系可以有很多不同的属性(和实现的细微差别),开发人员对如何实现它们没有一致的意见。
请参见我对2009年4月SO问题的扩展回答。
c++社区中定义OOP对象之间“组合”的属性(这个信念仍然被广泛持有):两个相关对象(组合及其组件)之间的运行时生命周期依赖关系并不是“组合”的真正特征,因为在其他类型的关联中,我们也可以由于引用完整性而具有这种依赖关系。
例如,在一个SO回答中提出了以下“composition”的代码模式:
final class Car {
private final Engine engine;
Car(EngineSpecs specs) {
engine = new Engine(specs);
}
void move() {
engine.work();
}
}
被调查者声称这是“合成”的特征,没有其他类可以引用/知道这个组件。然而,并非所有可能的“组合”情况都是如此。特别是,在汽车引擎的情况下,汽车的制造商(可能是在另一个类的帮助下实现的)可能必须引用引擎,以便在出现问题时能够联系汽车的所有者。
[1] http://www.learncpp.com/cpp-tutorial/103-aggregation/
附录-关于StackOverflow上的组合与聚合的反复询问问题的不完整列表
[Apr 2009] Aggregation versus Composition [closed as primarily opinion-based by] [Apr 2009] What is the difference between Composition and Association relationship? [May 2009] Difference between association, aggregation and composition [May 2009] What is the difference between composition and aggregation? [duplicate] [Oct 2009] What is the difference between aggregation, composition and dependency? [marked as duplicate] [Nov 2010] Association vs. Aggregation [marked as duplicate] [Aug 2012] Implementation difference between Aggregation and Composition in Java [Feb 2015] UML - association or aggregation (simple code snippets)
推荐文章
- js:将一个组件包装成另一个组件
- 如何在方法中访问“静态”类变量?
- 为什么c#不提供c++风格的'friend'关键字?
- String, StringBuffer和StringBuilder
- 显示所有Elasticsearch聚合结果/桶,而不仅仅是10个
- 存储库和服务层的区别?
- DDD -实体不能直接访问存储库的规则
- 为什么STL如此严重地基于模板而不是继承?
- 如何在Objective-C中声明类级属性?
- 面向方面编程与面向对象编程
- c++中类似于java的instanceof
- 在python中遍历对象属性
- 将类代码分离为头文件和cpp文件
- 在PHP中使用getter和setter而不是函数或简单的公共字段有什么优点?
- 基于原型的继承与基于类的继承