关联、聚合和组合之间的区别是什么? 请从实施的角度加以说明。
当前回答
在一个非常简单的句子中: 聚合和组合是关联的子集。
A使用B ->这是一个聚合 A需要B ->是复合。
点击这里阅读更多。
其他回答
我知道这个问题被标记为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的作者,并在上面添加了相关帖子的链接以获取更多信息。
联想是关系的广义概念。它包括组合和聚合。
组合(混合)是一种将简单对象或数据类型包装成单个单元的方法。组合是许多基本数据结构的关键构建块
聚合(将许多事物形成一个集群)不同于普通的组合,因为它不意味着所有权。在组合中,当拥有的对象被销毁时,包含的对象也被销毁。总的来说,这并不一定正确。
记住区别的技巧:
“有一个”:聚合 “局部”:comPOsitoin “是一个”:继承
context | Aggregation | Composition |
---|---|---|
Life time | objects have their own lifetime and there is no owner | controlled by whole or parent that owns it |
Scope | parent objects and child objects are independent | parent object also means the death of its children. |
Relationship | Has-a | Part-of |
Strength | weak relationship | strong relationship. |
Real-life example | Car and Driver | Car and wheels |
现在让我们观察下面的图像
类比:
合成:下图是图像合成,即使用单独的图像合成一张图像。
聚合:图像在单一位置的集合
例如,A大学有多个系,每个系都有一些教授。如果大学关闭,这些部门将不复存在,但这些部门的教授将继续存在。因此,一所大学可以被看作是一个系的组成部分,而系则是教授的集合。此外,教授可以在一个以上的部门工作,但一个部门不能属于一所以上的大学。
It's important to understand why we should even bother with using more than once relationship line. The most obvious reason is to describe parent-child relationship between classes (when parent deleted all its child’s are deleted as a result), but more impotently, we want to distinguish between simple association and composition in order to place implicit restrictions on the visibility and propagation of changes to the related classes, a matter which plays an important role in understanding and reducing system complexity.
协会
描述类之间静态关系的最抽象的方法是使用Association链接,它简单地说明两个或多个类之间存在某种类型的链接或依赖关系。
弱协会
类a可以链接到类b,以显示其方法之一包含类b实例的参数,或返回类b实例。
强大的协会
类a也可以被链接到类b,以显示它持有对类b实例的引用。
聚合(共享关联)
在类a(整体)和类b(部分)之间存在部分关系的情况下,我们可以更具体地使用聚合链接而不是关联链接,强调类b也可以由应用程序中的其他类聚合(因此聚合也称为共享关联)。
需要注意的是,聚合链接并没有以任何方式说明ClassA拥有ClassB,也没有说明两者之间存在父子关系(当父类删除其所有子类时,其结果也将被删除)。事实上,恰恰相反!聚合链接通常用于强调ClassA不是ClassB的独占容器,因为实际上ClassB有另一个容器。
聚合vs .关联 关联链接在任何情况下都可以取代聚合链接,而聚合不能在类之间只有“弱链接”的情况下取代关联,即类a有包含类b参数的方法,但类a不包含对类b实例的引用。
马丁·福勒认为聚合链接根本不应该使用,因为它没有附加价值,而且会扰乱一致性,引用吉姆·拉姆博的话:“把它看作建模安慰剂”。
组合(非共享关联)
我们应该更具体地使用复合链接,在这种情况下,除了类a和类b之间的部分关系之外——两者之间有很强的生命周期依赖关系,这意味着当类a被删除时,ClassB也会被删除
复合链接表明一个类(容器,整体)对其他类(部分)具有独占所有权,这意味着容器对象及其部分构成了父子关系。
与关联和聚合不同,在使用组合关系时,组合类不能作为组合类的返回类型或参数类型出现。因此,对组合类的更改不能传播到系统的其余部分。因此,随着系统的增长,组合的使用限制了复杂性的增长。
测量系统复杂性
System complexity can be measured simply by looking at a UML class diagram and evaluating the association, aggregation, and composition relationship lines. The way to measure complexity is to determine how many classes can be affected by changing a particular class. If class A exposes class B, then any given class that uses class A can theoretically be affected by changes to class B. The sum of the number of potentially affected classes for every class in the system is the total system complexity.
你可以在我的博客上阅读更多: http://aviadezra.blogspot.com/2009/05/uml-association-aggregation-composition.html
协会
关联表示两个类之间的关系。它可以是单向的(单向)或双向的(双向)
例如:
单向
客户下单
双向
A和B结婚了 B和A结婚了
聚合
聚合是一种关联。但是有特定的特征。聚合是一个较大的“整体”类包含一个或多个较小的“部分”类之间的关系。相反,一个较小的“部分”类是“整个”较大类的一部分。
例如:
俱乐部有会员
一个俱乐部(“整体”)是由几个俱乐部成员(“部分”)组成的。会员可以在俱乐部外生活。如果俱乐部(“整体”)死亡,成员(“部分”)不会随之死亡。因为会员可以属于多个俱乐部(“整体”)。
作文
这是一种更强的聚合形式。“整体”对其“部分”的创造或破坏负责
例如:
学校有院系
在这种情况下,学校(“整体”)将消亡,部门(“部分”)将随之消亡。 因为每个部分只能属于一个“整体”。
组合(如果你删除“整体”,“部分”也会自动删除-“所有权”)
在新类中创建现有类的对象。这称为组合,因为新类是由现有类的对象组成的。 通常使用普通成员变量。 如果组合类自动处理负责创建/销毁子类的分配/回收,则可以使用指针值。
c++中的复合
#include <iostream>
using namespace std;
/********************** Engine Class ******************/
class Engine
{
int nEngineNumber;
public:
Engine(int nEngineNo);
~Engine(void);
};
Engine::Engine(int nEngineNo)
{
cout<<" Engine :: Constructor " <<endl;
}
Engine::~Engine(void)
{
cout<<" Engine :: Destructor " <<endl;
}
/********************** Car Class ******************/
class Car
{
int nCarColorNumber;
int nCarModelNumber;
Engine objEngine;
public:
Car (int, int,int);
~Car(void);
};
Car::Car(int nModelNo,int nColorNo, int nEngineNo):
nCarModelNumber(nModelNo),nCarColorNumber(nColorNo),objEngine(nEngineNo)
{
cout<<" Car :: Constructor " <<endl;
}
Car::~Car(void)
{
cout<<" Car :: Destructor " <<endl;
Car
Engine
Figure 1 : Composition
}
/********************** Bus Class ******************/
class Bus
{
int nBusColorNumber;
int nBusModelNumber;
Engine* ptrEngine;
public:
Bus(int,int,int);
~Bus(void);
};
Bus::Bus(int nModelNo,int nColorNo, int nEngineNo):
nBusModelNumber(nModelNo),nBusColorNumber(nColorNo)
{
ptrEngine = new Engine(nEngineNo);
cout<<" Bus :: Constructor " <<endl;
}
Bus::~Bus(void)
{
cout<<" Bus :: Destructor " <<endl;
delete ptrEngine;
}
/********************** Main Function ******************/
int main()
{
freopen ("InstallationDump.Log", "w", stdout);
cout<<"--------------- Start Of Program --------------------"<<endl;
// Composition using simple Engine in a car object
{
cout<<"------------- Inside Car Block ------------------"<<endl;
Car objCar (1, 2,3);
}
cout<<"------------- Out of Car Block ------------------"<<endl;
// Composition using pointer of Engine in a Bus object
{
cout<<"------------- Inside Bus Block ------------------"<<endl;
Bus objBus(11, 22,33);
}
cout<<"------------- Out of Bus Block ------------------"<<endl;
cout<<"--------------- End Of Program --------------------"<<endl;
fclose (stdout);
}
输出
--------------- Start Of Program --------------------
------------- Inside Car Block ------------------
Engine :: Constructor
Car :: Constructor
Car :: Destructor
Engine :: Destructor
------------- Out of Car Block ------------------
------------- Inside Bus Block ------------------
Engine :: Constructor
Bus :: Constructor
Bus :: Destructor
Engine :: Destructor
------------- Out of Bus Block ------------------
--------------- End Of Program --------------------
聚合(如果你删除“整体”,“部分”可以存在-“无所有权”)
聚合是一种特定类型的组合,其中不暗示复杂对象和子对象之间的所有权。当一个聚合被销毁时,子对象不会被销毁。 通常使用指针变量/引用变量指向在聚合类作用域之外的对象 可以使用指向在聚合类范围之外的对象的引用值吗 不负责创建/销毁子类
c++中的聚合代码
#include <iostream>
#include <string>
using namespace std;
/********************** Teacher Class ******************/
class Teacher
{
private:
string m_strName;
public:
Teacher(string strName);
~Teacher(void);
string GetName();
};
Teacher::Teacher(string strName) : m_strName(strName)
{
cout<<" Teacher :: Constructor --- Teacher Name :: "<<m_strName<<endl;
}
Teacher::~Teacher(void)
{
cout<<" Teacher :: Destructor --- Teacher Name :: "<<m_strName<<endl;
}
string Teacher::GetName()
{
return m_strName;
}
/********************** Department Class ******************/
class Department
{
private:
Teacher *m_pcTeacher;
Teacher& m_refTeacher;
public:
Department(Teacher *pcTeacher, Teacher& objTeacher);
~Department(void);
};
Department::Department(Teacher *pcTeacher, Teacher& objTeacher)
: m_pcTeacher(pcTeacher), m_refTeacher(objTeacher)
{
cout<<" Department :: Constructor " <<endl;
}
Department::~Department(void)
{
cout<<" Department :: Destructor " <<endl;
}
/********************** Main Function ******************/
int main()
{
freopen ("InstallationDump.Log", "w", stdout);
cout<<"--------------- Start Of Program --------------------"<<endl;
{
// Create a teacher outside the scope of the Department
Teacher objTeacher("Reference Teacher");
Teacher *pTeacher = new Teacher("Pointer Teacher"); // create a teacher
{
cout<<"------------- Inside Block ------------------"<<endl;
// Create a department and use the constructor parameter to pass the teacher to it.
Department cDept(pTeacher,objTeacher);
Department
Teacher
Figure 2: Aggregation
} // cDept goes out of scope here and is destroyed
cout<<"------------- Out of Block ------------------"<<endl;
// pTeacher still exists here because cDept did not destroy it
delete pTeacher;
}
cout<<"--------------- End Of Program --------------------"<<endl;
fclose (stdout);
}
输出
--------------- Start Of Program --------------------
Teacher :: Constructor --- Teacher Name :: Reference Teacher
Teacher :: Constructor --- Teacher Name :: Pointer Teacher
------------- Inside Block ------------------
Department :: Constructor
Department :: Destructor
------------- Out of Block ------------------
Teacher :: Destructor --- Teacher Name :: Pointer Teacher
Teacher :: Destructor --- Teacher Name :: Reference Teacher
--------------- End Of Program --------------------
推荐文章
- 是什么导致这个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个
- 存储库和服务层的区别?