关联、聚合和组合之间的区别是什么? 请从实施的角度加以说明。
当前回答
依赖性(引用) 这意味着两个物体之间没有概念上的联系。例如: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();
}
}
其他回答
我想这个链接可以帮到你:http://ootips.org/uml-hasa.html
为了理解这些术语,我记得我早期编程时的一个例子:
如果你有一个" chess board "对象它包含" box "对象那就是组合因为如果" chess board "被删除了盒子就没有理由再存在了。
如果你有一个'square'对象,它有一个'color'对象,正方形被删除了,'color'对象可能仍然存在,这就是聚合
它们都是关联,主要的区别是概念上的
https://www.linkedin.com/pulse/types-relationships-object-oriented-programming-oop-sarah-el-dawody/
Composition:是一种“part-of”关系。
例如,“发动机是汽车的一部分”,“心脏是身体的一部分”。
关联:是“has-a”类型的关系
例如,假设我们有两个类,那么这两个类被称为“has-a”关系,如果这两个实体为了某些工作而共享彼此的对象,同时它们可以不依赖彼此而存在,或者它们都有自己的生命期。
上面的示例显示了一种关联关系,因为Employee类和Manager类都使用彼此的对象,并且都有各自独立的生命周期。
聚合:是基于“has-a”关系,是一种特殊的关联形式
例如,“学生”和“地址”。每个学生必须有一个地址,所以学生类和地址类之间的关系将是“Has-A”类型的关系,反之亦然。
我想说明如何在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
在面向对象编程中,类是相互关联的。这意味着它们的实例相互调用方法。因此,如果一个类的实例调用另一个类的方法,它们是相关的,通常我们用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的一个对象,你会有这样的东西(在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个
- 存储库和服务层的区别?