关联、聚合和组合之间的区别是什么? 请从实施的角度加以说明。
当前回答
这些答案的问题在于,它们只说了一半:它们解释了聚合和组合是关联的形式,但没有说一个关联是否可能不是这两种形式。
基于对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 ->这是一个聚合 A需要B ->是复合。
点击这里阅读更多。
我想说明如何在Rails中实现这三个术语。ActiveRecord将两个模型之间的任何类型的关系称为关联。在阅读文档或文章时,人们不会经常发现术语组合和聚合与ActiveRecord相关。通过向类的主体中添加一个关联类宏来创建关联。其中一些宏是belongs_to, has_one, has_many等。
If we want to set up a composition or aggregation, we need to add belongs_to to the owned model (also called child) and has_one or has_many to the owning model (also called parent). Wether we set up composition or aggregation depends on the options we pass to the belongs_to call in the child model. Prior to Rails 5, setting up belongs_to without any options created an aggregation, the child could exist without a parent. If we wanted a composition, we needed to explicitly declare this by adding the option required: true:
class Room < ActiveRecord::Base
belongs_to :house, required: true
end
在Rails 5中,这一点被改变了。现在,声明belongs_to关联在默认情况下创建了一个组合,子元素不能没有父元素而存在。所以上面的例子可以重写为:
class Room < ApplicationRecord
belongs_to :house
end
如果我们想要允许子对象在没有父对象的情况下存在,我们需要通过选项optional显式地声明这一点
class Product < ApplicationRecord
belongs_to :category, optional: true
end
摘自: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.
我们称这些关系为聚合,其对象具有独立的生命周期,但存在所有权,并且子对象不能属于另一个父对象。让我们以手机和电池为例。单个电池可以属于一个手机,但如果手机停止工作,我们从数据库中删除它,手机电池将不会被删除,因为它可能仍在工作。因此,在聚合中,虽然有所有权,但对象有它们的生命周期
我们使用术语组合来指代对象没有独立生命周期的关系,如果父对象被删除,所有子对象也将被删除。让我们以问题和答案之间的关系为例。一个问题可以有多个答案,答案不能属于多个问题。如果我们删除问题,答案将自动删除。
摘自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
};
关联是两个独立的类之间的关系,关联可以是任何类型,比如one to one, one to may等等。它连接了两个完全独立的实体。
聚合是一种特殊形式的关联,它是类(或实体)之间的单向关系,例如钱包类和货币类。钱包里有钱,但钱不一定要有钱包,所以这是一种单向关系。在这种关系中,如果另一个条目结束,两个条目都可以存活。在我们的例子中,如果Wallet类不存在,并不意味着Money类不存在。
复合是聚合的一种受限形式,其中两个实体(或者可以说类)高度依赖于彼此。例如:人与心。人需要心脏才能生存,心脏也需要人体才能生存。换句话说,当类(实体)是相互依赖的,它们的生命周期是相同的(如果一个死了,另一个也死了),那么它就是一个复合。如果人类职业不存在,心脏职业就没有意义。
推荐文章
- 是什么导致这个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个
- 存储库和服务层的区别?