关联,聚合和组合有什么区别?

时间:2009-05-20 02:47:50

标签: associations uml aggregation composition

关联,聚合和组合有什么区别? 请在实施方面解释。

19 个答案:

答案 0 :(得分:318)

对于两个对象FooBar,可以定义关系

协会 - 我与某个对象有关系。 Foo使用Bar

public class Foo { 
    void Baz(Bar bar) {
    } 
};

撰写 - 我拥有一个对象,我对其生命负责。当Foo死亡时,Bar

也会死亡
public class Foo {
    private Bar bar = new Bar(); 
}

聚合 - 我有一个我从别人那里借来的东西。当Foo死亡时,Bar可能会继续存在。

public class Foo { 
    private Bar bar; 
    Foo(Bar bar) { 
       this.bar = bar; 
    }
}

答案 1 :(得分:100)

我知道这个问题被标记为C#但这里的概念非常通用questions like this重定向。所以我将在这里提供我的观点(从Java的角度来看有点偏向于我更舒服)。

当我们想到面向对象的本质时,我们总是会想到对象,类(对象蓝图)以及它们之间的关系。对象通过方法相互关联并相互交互。换句话说,一个类的对象可以使用由另一个类的对象提供的服务/方法。这种关系被称为关联。

聚合和组合是关联的子集,这意味着它们是特定的关联案例。

enter image description here

  • 在一个类的聚合和组合对象"拥有"另一个类的对象
  • 但是有一个微妙的区别。在组合中,由其拥有的类的对象所拥有的类的对象不能依赖于它自己的(也称为"死亡关系")。它将始终作为其拥有对象的一部分,其中聚合依赖对象独立,即使拥有类的对象已死亡也可以存在。
  • 因此,在合成中,如果拥有对象是垃圾收集的,那么拥有的对象也将不是聚合中的情况。

困惑?

组合示例:考虑汽车和发动机的示例,该发动机非常特定于该汽车(意味着它不能用于任何其他汽车)。 Car SpecificEngine 类之间的这种关系称为Composition。没有SpecificEngine类的对象,Car类的对象不能存在,并且没有Car类,SpecificEngine的对象没有意义。用简单的话来说,Car class only"拥有" SpecificEngine类。

汇总示例:现在考虑班级汽车和班级。汽车需要Wheel对象才能运行。这意味着Car对象拥有Wheel对象但我们不能说没有Car对象时Wheel对象没有意义。它可以很好地用于自行车,卡车或不同的汽车对象。

总结 -

总结一下,关联是一个非常通用的术语,用于表示类何时使用另一个类提供的功能。如果一个父类对象拥有另一个子类对象,并且该子类对象在没有父类对象的情况下无法有意义地存在,我们就会说它的组合。如果它可以,那么它被称为聚合。

More details here. 我是http://opensourceforgeeks.blogspot.in的作者,并在相关帖子上方添加了一个链接,以获取更多背景信息。

答案 2 :(得分:67)

协会是关系的概括概念。它包括组合和聚合。

合成混合)是一种将简单对象或数据类型包装到单个单元中的方法。组合是许多基本数据结构的关键构建块

聚合集合)与普通作品的不同之处在于它并不意味着所有权。在组合中,当拥有对象被破坏时,包含的对象也被破坏。在汇总中,这不一定是真的。

  

两者都表示物体之间的关系,只是力量不同。

请记住差异: A - A ggregation和 O wn - c O mpositoin < / p>

enter image description here

现在让我们观察以下图片

relations

enter image description here

类比:

构图:下面的图片是图像合成,即使用制作一个图像的单个图像 enter image description here

聚合:单个位置的图像集合

enter image description here

For example,一所大学拥有各个部门,每个部门都有一些教授。如果大学关闭,部门将不复存在,但这些部门的教授将继续存在。因此,大学可以被视为一个部门的组合,而部门则有教授的集合。此外,教授可以在多个部门工作,但一个部门不能成为一所以上大学的一部分。

答案 3 :(得分:40)

依赖(参考)
这意味着两个对象之间没有概念上的联系。例如EnrollmentService对象引用Student&amp;课程对象(作为方法参数或返回类型)

public class EnrollmentService {
    public void enroll(Student s, Course c){}
}

协会(has-a)
这意味着对象之间几乎总是存在链接(它们是关联的)。 订单对象 具有 客户对象

public class Order {
    private Customer customer
}

聚合(has-a +整体)
两个对象之间存在整体关系的特殊关联。他们可能没有彼此生活。

public class PlayList{
    private List<Song> songs;
}

注意:最棘手的部分是区分聚合与正常关联。老实说,我认为这是不同的解释。

作文(has-a +整体+所有权)
特殊的聚合。 Apartment由一些Room组成。没有RoomApartment就不能存在。当公寓被删除时,所有相关的房间也会被删除。

public class Apartment{
    private Room bedroom;
    public Apartment() {
       bedroom = new Room();
    }
}

答案 4 :(得分:28)

来自Robert Martin in comp.object的帖子:

Association表示一个实例将消息发送到另一个实例的能力。这通常使用指针或引用实例变量实现,尽管它也可以实现为方法参数或创建局部变量。

//[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
};

答案 5 :(得分:21)

正如其他人所说,关联是对象之间的关系,聚合和组合是关联的类型。

从实施的角度来看,通过让一个类成员通过引用来获得聚合。例如,如果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;
    }
};

重要的一点是,在合成中,容器对象拥有所包含的容器对象,而在聚合中,引用它。

答案 6 :(得分:12)

令人惊讶的是,关于三个关系概念关联聚合组合之间的区别存在多少混淆。

请注意,术语聚合组合已经在C ++社区中使用,可能已经有一段时间被定义为 association <的特殊情况/ em> in UML Class Diagrams。

主要问题是广泛且持续的误解(即使在专业软件开发人员中),构成的概念意味着整体与其部分之间的生命周期依赖性,使得部分在没有整体的情况下不能存在,忽略了这样的事实:还存在与不可共享部分的部分整体关联的情况,其中部分可以从整体中分离并且在整个的破坏中存活。

据我所知,这种混乱有两个根源:

  1. 在C ++社区中,术语&#34;聚合&#34;在定义用于引用另一个独立类的对象的属性的类的意义上使用(参见,例如,[1]),这是UML类图中的关联的意义。术语&#34;组成&#34;用于为其对象定义组件对象的类,这样在销毁复合对象时,这些组件对象也会被销毁。

  2. 在UML类图中,&#34;聚合&#34;和&#34;组成&#34;已经被定义为代表 部分 - 整体 关系的关联的特殊情况(已经在哲学中讨论了很长时间)。在他们的定义中,&#34;聚合&#34;之间的区别。和#34;组成&#34;基于这样的事实:它是否允许在两个或更多整体之间共享一部分。他们定义&#34;组合&#34;拥有不可共享(独家)的部分,而&#34;聚合&#34;可以分享他们的部分。此外,他们会说出以下内容:经常,但并非在所有情况下,组合在整体与其各部分之间存在生命周期依赖性,使得部分在没有整体的情况下不能存在。

  3. 因此,虽然UML已经将术语&#34;聚合&#34;和&#34;组成&#34;在正确的上下文(部分 - 整体关系)中,他们没有设法以清晰明确的方式定义它们,捕捉开发人员的直觉。但是,这并不奇怪,因为这些关系可能有很多不同的属性(和实现细微差别),开发人员不会就如何实现它们进行协商。

    另见my extended answer以下列出的2009年4月的SO问题。

    假定定义&#34;组成的属性&#34;在C ++社区中的OOP对象之间(并且这种信念仍被广泛持有):两个相关对象(复合及其组件)之间的运行时生命周期依赖性并不是&#34;组合&#34的真正特征;因为在其他类型的关联中,由于引用完整性,我们也可以有这样的依赖。

    例如,以下代码模式为&#34;组合&#34;是an SO answer中提出的:

    final class Car {    
      private final Engine engine;
    
      Car(EngineSpecs specs) {
        engine = new Engine(specs);
      }
    
      void move() {
        engine.work();
      }
    }
    

    受访者声称这将是&#34;组成&#34;没有其他类可以引用/知道该组件。然而,对于所有可能的&#34;组合&#34;情况肯定不是这样。特别是在汽车发动机的情况下,汽车制造商可能在另一个类别的帮助下实施,可能必须参考发动机以便能够在那里接触汽车的所有者是一个问题。

    [1] http://www.learncpp.com/cpp-tutorial/103-aggregation/

    附录 - StackOverflow上关于构图与聚合的重复问题的不完整列表

    [ 2009年4月]
    Aggregation versus Composition [以主要意见为基础关闭] [ 2009年4月]
    What is the difference between Composition and Association relationship? [ 2009年5月]
    Difference between association, aggregation and composition
    [ 2009年5月]
    What is the difference between composition and aggregation? [重复]
    [ 2009年10月]
    What is the difference between aggregation, composition and dependency? [标记为重复]
    [ 2010年11月]
    Association vs. Aggregation [标记为重复]
    [ 2012年8月]
    Implementation difference between Aggregation and Composition in Java
    [ 2015年2月]
    UML - association or aggregation (simple code snippets)

答案 7 :(得分:12)

重要的是要理解为什么我们甚至不应该使用不止一次的关系线。最明显的原因是描述类之间的父子关系(当父删除它的所有子项时因此而被删除),但更重要的是,我们想要区分简单的关联和组合,以便对可见性和将更改传播到相关类,这一点在理解和降低系统复杂性方面起着重要作用。

  

协会

描述类之间静态关系的最抽象方式是使用Association链接,它简单地指出在两个或更多类之间存在某种链接或依赖关系。

弱协会

ClassA可能链接到ClassB,以显示其中一个方法包含ClassB实例的参数,或返回ClassB的实例。

强有力的协会

ClassA也可以链接到ClassB,以表明它拥有对ClassB实例的引用。

  

聚合(共享关联)

在ClassA(整体)和ClassB(部分)之间存在部分关系的情况下,我们可以更具体并使用聚合链接而不是关联链接,突出显示ClassB也可以由其他类聚合应用程序(因此聚合也称为共享关联)。

enter image description here

重要的是要注意,聚合链接不以任何方式表明ClassA拥有ClassB,也没有说明两者之间存在父子关系(当父删除其所有子节点时)。实际上,恰恰相反!聚合链接通常用于强调ClassA不是ClassB的独占容器,因为事实上ClassB有另一个容器。

聚合对比协会 关联链接可以在每种情况下替换聚合链接,而聚合不能在类之间只有“弱链接”的情况下替换关联,即ClassA具有包含ClassB参数的方法,但ClassA不包含对类的参数ClassB实例。

Martin Fowler建议不应该使用聚合链接,因为它没有附加价值而且会影响一致性,引用Jim Rumbaugh“将其视为建模安慰剂”。

  

作文(非共享协会)

除了ClassA和ClassB之间的部分关系之外,我们应该更具体并使用组合链接 - 两者之间存在强烈的生命周期依赖关系,这意味着当删除ClassA时,ClassB也会被删除为结果

enter image description here

组合链接显示类(容器,整体)对其他类(部分)具有独占所有权,这意味着容器对象及其部分构成父子关系。

与关联和聚合不同,使用组合关系时,组合类不能显示为复合类的返回类型或参数类型。因此,对组合类的更改不能传播到系统的其余部分。因此,随着系统的发展,组合的使用限制了复杂性的增长。

  

测量系统复杂性

系统复杂性可以通过查看UML类图并评估关联,聚合和组合关系线来简单地测量。衡量复杂性的方法是通过更改特定类来确定可以影响的类数。如果类A公开了类B,那么任何使用类A的给定类理论上都会受到类B更改的影响。系统中每个类的可能受影响类的数量总和就是系统的总体复杂性。

您可以在我的博客上阅读更多内容: http://aviadezra.blogspot.com/2009/05/uml-association-aggregation-composition.html

答案 8 :(得分:11)

<强> 协会

Association表示两个类之间的关系。它可以是单向(单向)或双向(双向)

例如:

  1. 单向
  2.   

    客户下订单

    1. 双向
    2.   

      A与B结婚

           

      B与A结婚

      <强> 聚合

      聚合是一种关联。但具有特定的特征。聚合是一个更大的整体关系。 class包含一个或多个较小的&#34;部分&#34;相反,一个较小的部分&#34; class是&#34;整体&#34;的一部分。更大的班级。

      例如:

        

      俱乐部有会员

      一个俱乐部(&#34;整个&#34;)由几个俱乐部成员组成(&#34;部分&#34;)。会员在俱乐部外有生命。如果俱乐部(&#34;整个&#34;)要死,会员(&#34;部分&#34;)就不会死。因为会员可以属于多个俱乐部(&#34;整个&#34;)。

      <强> 组合物

      这是一种更强大的聚合形式。&#34;整体&#34;负责创建或销毁其部件&#34;

      例如:

        

      学校有部门

      在这种情况下,学校(&#34;整体&#34;)将死亡,部门(&#34;部分&#34;)将会死亡。 因为每个部分只能属于一个&#34;整个&#34;。

答案 9 :(得分:7)

构图(如果删除“整体”,“部分”也会自动删除 - “所有权”)

  • 在新类中创建现有类的对象。这称为组合,因为新类由现有类的对象组成。

  • 通常使用普通成员变量。

  • 如果组合类自动处理负责创建/销毁子类的分配/解除分配,则可以使用指针值。

enter image description here

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 --------------------

聚合(如果删除“整体”,则“部分”可以存在 - “无所有权”)

  • 聚合是一种特定类型的合成,其中隐含了复杂对象和子对象之间的所有权。当聚合被销毁时,子对象不会被销毁。

  • 通常使用指针变量/引用变量指向超出聚合类范围的对象

  • 可以使用指向超出聚合类范围的对象的引用值

  • 不负责创建/销毁子类

enter image description here

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 --------------------

答案 10 :(得分:5)

<强>组合物: 这是一旦你摧毁一个物体(学校),另一个绑定它的物体(教室)也会被摧毁。它们都不能独立存在。

<强>聚合: 这与上面的(Composition)关联完全相反,一旦你杀死一个对象(Company),绑定到它的另一个对象(Employees)就可以存在于它自己的。

<强>协会即可。
组合和聚合是两种形式的关联。

答案 11 :(得分:5)

这些答案的问题在于它们只是故事的一半:它们解释了聚合和组合是关联的形式,但是他们不会说关联是否可能不是那些。

我根据SO上的许多帖子和一些UML文档的一些简要读物收集,有4种主要的具体形式的类关联:

  1. 组成:A由A组成;如果没有A,B就不存在,就像家里的房间一样
  2. 聚合:A有一个B; B可以在没有A的情况下存在,就像教室里的学生一样
  3. 依赖:A使用-a B; A和B之间没有生命周期依赖关系,如方法调用参数,返回值或方法调用期间创建的临时值
  4. 概括:A是-a B
  5. 当两个实体之间的关系不是其中之一时,它可以被称为&#34;一个关联&#34;在一般意义上的术语,并进一步描述其他方式(注意,刻板印象等)。

    我的猜测是&#34;泛型协会&#34;主要用于两种情况:

    • 当关系的具体细节仍在制定中时;图中的这种关系应尽快转换为实际/将要的(其中4个)。
    • 当一个关系不匹配UML预定的那4个中的任何一个时; &#34;泛型&#34;协会仍然为你提供了一种表达一种关系的方式,这种关系不是其中一种关系,所以你不会因为一个错误的关系而被卡住了#34;这实际上并不是聚合,只是UML没有我们可以使用的任何其他符号&#34;

答案 12 :(得分:5)

我认为此链接将完成您的作业:http://ootips.org/uml-hasa.html

要理解我在早期编程时记住的一个例子:

如果你有一个'棋盘'对象,其中包含组合的'box'对象,因为如果'棋盘'被删除,则没有理由让这些盒子存在。

如果你有一个'正方形'对象有一个'颜色'对象并且正方形被删除,那么'颜色'对象可能仍然存在,即聚合

它们都是关联,主要区别在于概念

答案 13 :(得分:3)

https://www.linkedin.com/pulse/types-relationships-object-oriented-programming-oop-sarah-el-dawody/

组成:是“部分”关系。

例如“引擎是汽车的一部分”,“心脏是身体的一部分”。

enter image description here

关联:是一种“具有”类型的关系

例如,假设我们有两个类,那么如果这两个实体在某些工作中共享彼此的对象,并且同时可以不存在彼此的依赖关系而存在,则这两个类被称为“具有”关系都有自己的一生。

enter image description here

上面的示例显示了由于Employee和Manager类使用彼此的对象以及它们各自独立的生命周期而导致的关联关系。

聚集:基于“具有”关系,是\\一种特殊的关联形式

例如“学生”和“地址”。每个学生都必须有一个地址,以便学生类和地址类之间的关系为“ Has-A”类型的关系,反之亦然。

enter image description here

答案 14 :(得分:2)

我想说明如何在Rails中实现这三个术语。 ActiveRecord调用两个模型association之间的任何类型的关系。在阅读与ActiveRecord相关的文档或文章时,人们不会经常发现术语compositionaggregation。通过将一个关联类宏添加到类的主体来创建关联。其中一些宏是belongs_tohas_onehas_many等。

如果我们要设置compositionaggregation,我们需要将belongs_to添加到自有模型(也称为子模型)和has_one或{{1}拥有模型(也称为父模型)。我们设置has_manycomposition取决于我们传递给子模型中aggregation调用的选项。在Rails 5之前,设置belongs_to而没有创建belongs_to的任何选项,孩子可能在没有父项的情况下存在。如果我们想要aggregation,我们需要通过添加选项composition明确声明这一点:

required: true

在Rails 5中,这已经改变了。现在,声明class Room < ActiveRecord::Base belongs_to :house, required: true end 关联默认情况下会创建belongs_to,如果没有父级,则子项不能存在。所以上面的例子可以重写为:

composition

如果我们想让子对象在没有父对象的情况下存在,我们需要通过选项class Room < ApplicationRecord belongs_to :house end

明确声明这一点。
optional

答案 15 :(得分:2)

    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.

答案 16 :(得分:0)

用一个非常简单的句子:
聚集和组成是关联的子集。

  • A使用B->这是一个聚合

  • A需要B->是构图。

了解更多here

答案 17 :(得分:0)

关联是两个单独的类之间的关系,关联可以是任何类型,例如一对一,一对一等。它连接了两个完全独立的实体。

聚集是一种特殊的关联形式,例如,是类(或实体)之间的单向单向关系。钱包和金钱类。电子钱包有钱,但是金钱不一定需要电子钱包,因此它是一种单向关系。在这种关系中,如果另一个结束,则两个条目都可以生存。在我们的示例中,如果不存在Wallet类,则并不意味着Money类不存在。

组成是聚合的一种受限形式,其中两个实体(或您可以说是类)彼此高度依赖。例如人与心。人需要心脏才能生存,而心脏则需要人体才能生存。换句话说,当类别(实体)彼此依赖并且它们的寿命相同时(如果一个人死亡,另一个人也死亡),则其组成。如果没有人类阶级,那么心脏阶级就没有意义。

答案 18 :(得分:0)

来自:Remo H. Jansen的书“ Beginning React:Learning TypeScript 2.x-Second Edition”:

我们将关联称为那些对象具有独立生命周期且没有对象所有权的关系。让我们看一个老师和学生的例子。多个学生可以与一个老师关联,一个学生可以与多个老师关联,但是两者都有独立的生命周期(两者都可以独立创建和删除)。因此,当老师离开学校时,我们不需要删除任何学生,而当学生离开学校时,我们不需要删除任何老师。

我们将聚合称为那些对象具有独立生命周期但有所有权且子对象不能属于另一个父对象的关系。让我们以手机和手机电池为例。一块电池可以属于一部电话,但是如果该电话停止工作,并且我们从数据库中删除了该电池,则由于该电池仍可以工作,因此不会删除该电池。因此,在聚合中,尽管拥有所有权,但是对象具有生命周期

我们使用术语组成来指代其对象没有独立生命周期的关系,如果删除了父对象,则所有子对象也将被删除。让我们以问题和答案之间的关系为例。单个问题可以有多个答案,并且答案不能属于多个问题。如果我们删除问题,答案将自动删除。