关联、聚合和组合之间的区别是什么? 请从实施的角度加以说明。
当前回答
在面向对象编程中,类是相互关联的。这意味着它们的实例相互调用方法。因此,如果一个类的实例调用另一个类的方法,它们是相关的,通常我们用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。我们知道成绩单是非常依赖于学生的,如果我们从系统中删除了学生,他们的成绩单也应该被删除。
其他回答
我想这个链接可以帮到你:http://ootips.org/uml-hasa.html
为了理解这些术语,我记得我早期编程时的一个例子:
如果你有一个" chess board "对象它包含" box "对象那就是组合因为如果" chess board "被删除了盒子就没有理由再存在了。
如果你有一个'square'对象,它有一个'color'对象,正方形被删除了,'color'对象可能仍然存在,这就是聚合
它们都是关联,主要的区别是概念上的
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.
对于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;
}
}
这些答案的问题在于,它们只说了一半:它们解释了聚合和组合是关联的形式,但没有说一个关联是否可能不是这两种形式。
基于对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"
正如其他人所说,关联是对象之间的关系,聚合和组合是关联的类型。
从实现的角度来看,聚合是通过引用类成员来获得的。例如,如果类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个
- 存储库和服务层的区别?