关联、聚合和组合之间的区别是什么? 请从实施的角度加以说明。
当前回答
依赖性(引用) 这意味着两个物体之间没有概念上的联系。例如:enroll service对象引用Student & Course对象(作为方法参数或返回类型)
public class EnrollmentService {
public void enroll(Student s, Course c){}
}
协会(有) 这意味着对象之间几乎总是有一个链接(它们是相关联的)。 Order对象有一个Customer对象
public class Order {
private Customer customer
}
聚合(has-a + whole-part) 两个对象之间存在整体-部分关系的一种特殊联想。但他们可能没有彼此。
public class PlayList {
private List<Song> songs;
}
OR
public class Computer {
private Monitor monitor;
}
注意:最棘手的部分是区分聚合和普通关联。老实说,我认为这有不同的解释。
组成(has-a +整体部分+所有权) 一种特殊的聚合。公寓是由一些房间组成的。没有公寓,就没有房间。删除一个公寓时,所有关联的房间也会被删除。
public class Apartment{
private Room bedroom;
public Apartment() {
bedroom = new Room();
}
}
其他回答
成分: 一旦你摧毁了一个对象(学校),另一个与之绑定的对象(教室)也会被摧毁。两者都不能独立存在。
聚合: 这与上面的(Composition)关联完全相反,在上面的关联中,一旦你杀死了一个对象(Company),绑定到它的另一个对象(Employees)就可以独立存在。
协会。 组合和聚合是关联的两种形式。
令人惊讶的是,关于关联、聚合和组合这三个关系概念之间的区别存在如此多的混淆。
请注意,术语聚合和组合已经在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)
我想这个链接可以帮到你: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;
}
}
正如其他人所说,关联是对象之间的关系,聚合和组合是关联的类型。
从实现的角度来看,聚合是通过引用类成员来获得的。例如,如果类A聚合类B的一个对象,你会有这样的东西(在c++中):
class A {
B & element;
// or B * element;
};
聚合的语义是,当对象A被销毁时,它所存储的对象B仍然存在。当使用组合时,你有一个更强的关系,通常通过按值存储成员:
class A {
B element;
};
在这里,当一个A对象被销毁时,它所包含的B对象也将被销毁。最简单的方法是按值存储成员,但你也可以使用智能指针,或在析构函数中删除成员:
class A {
std::auto_ptr<B> element;
};
class A {
B * element;
~A() {
delete B;
}
};
重要的一点是,在组合中,容器对象拥有被包含的对象,而在聚合中,它引用它。
推荐文章
- 是什么导致这个ActiveRecord::ReadOnlyRecord错误?
- 在Java中使用“final”修饰符
- Rails:dependent =>:destroy VS:dependent =>:delete_all
- 我怎么知道什么时候创建一个接口?
- 构造函数vs工厂方法
- 在PHP5中创建单例设计模式
- 什么是依赖倒置原则?为什么它很重要?
- 从Java项目生成UML类图
- 为什么在Python方法中需要显式地有“self”参数?
- js:将一个组件包装成另一个组件
- 如何在方法中访问“静态”类变量?
- 为什么c#不提供c++风格的'friend'关键字?
- String, StringBuffer和StringBuilder
- 显示所有Elasticsearch聚合结果/桶,而不仅仅是10个
- 存储库和服务层的区别?