关联、聚合和组合之间的区别是什么? 请从实施的角度加以说明。
当前回答
Simple rules:
A "owns" B = Composition : B has no meaning or purpose in the system
without A
A "uses" B = Aggregation : B exists independently (conceptually) from A
A "belongs/Have" B= Association; And B exists just have a relation
Example 1:
A Company is an aggregation of Employees.
A Company is a composition of Accounts. When a Company ceases to do
business its Accounts cease to exist but its People continue to exist.
Employees have association relationship with each other.
Example 2: (very simplified)
A Text Editor owns a Buffer (composition). A Text Editor uses a File
(aggregation). When the Text Editor is closed,
the Buffer is destroyed but the File itself is not destroyed.
其他回答
我知道这个问题被标记为c#,但概念是非常一般的问题,就像这里的这个重定向。所以我将在这里提供我的观点(从java的角度来看,我更舒服)。
当我们想到面向对象的本质时,我们总是想到对象、类(对象蓝图)以及它们之间的关系。对象之间通过方法相互关联和交互。换句话说,一个类的对象可以使用另一个类的对象提供的服务/方法。这种关系被称为关联。
聚合和组合是关联的子集,这意味着它们是关联的特定情况。
In both aggregation and composition object of one class "owns" object of another class. But there is a subtle difference. In Composition the object of class that is owned by the object of it's owning class cannot live on it's own(Also called "death relationship"). It will always live as a part of it's owning object where as in Aggregation the dependent object is standalone and can exist even if the object of owning class is dead. So in composition if owning object is garbage collected the owned object will also be which is not the case in aggregation.
困惑吗?
组合示例:以一辆汽车为例,它的发动机是这辆汽车特有的(意味着它不能用于任何其他汽车)。Car和SpecificEngine类之间的这种关系称为Composition。Car类的对象如果没有SpecificEngine类的对象就不能存在,而如果没有Car类,SpecificEngine的对象就没有意义。简单地说,Car类单独“拥有”SpecificEngine类。
聚合示例:现在考虑类Car和类Wheel。Car需要一个Wheel对象来运行。这意味着Car对象拥有Wheel对象,但我们不能说没有Car对象,Wheel对象就没有意义。它可以很好地用于自行车,卡车或不同的汽车对象。
总结一下
总而言之,关联是一个非常通用的术语,用于表示一个类使用另一个类提供的功能。如果一个父类对象拥有另一个子类对象,并且没有父类对象,这个子类对象就不能有意义地存在,我们就说它是复合。如果可以,则称为聚合。
详情请点击这里。 我是http://opensourceforgeeks.blogspot.in的作者,并在上面添加了相关帖子的链接以获取更多信息。
摘自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
};
在面向对象编程中,类是相互关联的。这意味着它们的实例相互调用方法。因此,如果一个类的实例调用另一个类的方法,它们是相关的,通常我们用ASSOCIATION来建模这种关系。 例如,在下面的代码片段中,Customer类与Order类相关联。她/他取消了订单。
class Customer {
private Order[] orders;
public boolean removeCart() {
for (int i = 0 ; i < orders.length ; i++) {
orders[i].cancel();
}
}
}
AGGREGATION意味着一个类拥有另一个类的一些实例。它只不过是联想,马丁·福勒建议不要使用它。因为当一个类与另一个类相关联时,它有一个对该类的引用来调用该类上的方法。
但是COMPOSITION是关联的一个有意义的子集。这意味着一个类是由其他一些类组成的。例如,我们有一个学生类,由其他一些类组成,如ReportCard。我们知道成绩单是非常依赖于学生的,如果我们从系统中删除了学生,他们的成绩单也应该被删除。
在一个非常简单的句子中: 聚合和组合是关联的子集。
A使用B ->这是一个聚合 A需要B ->是复合。
点击这里阅读更多。
这些答案的问题在于,它们只说了一半:它们解释了聚合和组合是关联的形式,但没有说一个关联是否可能不是这两种形式。
基于对SO和一些UML文档的一些简要阅读,我收集到类关联有4种主要的具体形式:
A是由A组成的;没有A, B就不存在,就像家里的房间一样 聚合:A有A B;B可以没有A而存在,就像教室里的学生一样 依赖:A使用B;A和B之间没有生命周期依赖关系,比如方法调用参数、返回值或方法调用期间创建的临时对象 泛化:A是A
当两个实体之间的关系不是其中之一时,它可以被称为一般意义上的“关联”,并以其他方式进一步描述(注意,原型等)。
我的猜测是,“通用关联”主要用于两种情况:
when the specifics of a relationship are still being worked out; such relationship in a diagram should be converted as soon as possible to what it actually is/will be (one of the other 4). when a relationship doesn't match any of those 4 predetermined by UML; the "generic" association still gives you a way of representing a relationship that is "not one of the other ones", so that you aren't stuck using an incorrect relationship with a note "this is not actually aggregation, it's just that UML doesn't have any other symbol we could use"
推荐文章
- 是什么导致这个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个
- 存储库和服务层的区别?