以编程方式区分组合和聚合

Posted

技术标签:

【中文标题】以编程方式区分组合和聚合【英文标题】:Differentiating Composition and Aggregation programmatically 【发布时间】:2018-10-11 07:21:48 【问题描述】:

我正在通过下面的链接来找出组合和聚合之间的区别。

https://www.geeksforgeeks.org/association-composition-aggregation-java/

我能够理解,组合意味着孩子不能独立于父母而存在的关系,而聚合意味着孩子可以独立于父母而存在的关系。但无法理解我如何以编程方式区分它。下面是链接中给出的聚合和组合的示例。在这两种情况下,除了 Student 和 Department 类有一个额外的变量“name”之外,类在结构上是相同的。在组合中,“子不能独立于父”而存在,但是在这里我可以创建一个单独的 Book 对象并在不添加到 Library 的情况下使用它。

聚合

// student class
class Student 

    String name;
    int id ;
    String dept;

    Student(String name, int id, String dept) 
     
        this.name = name;
        this.id = id;
        this.dept = dept;
    




/* Department class contains list of student
Objects. It is associated with student
class through its Object(s). */
class Department 

    String name;
    private List<Student> students;

    Department(String name, List<Student> students) 
    
        this.name = name;
        this.students = students;    
    

    public List<Student> getStudents() 
    
        return students;
    

作曲

class Book 

    public String title;
    public String author;

    Book(String title, String author)
    
        this.title = title;
        this.author = author;
    


// Libary class contains 
// list of books.
class Library 

    // reference to refer to list of books.
    private final List<Book> books;

    Library (List<Book> books)
    
        this.books = books; 
    

    public List<Book> getTotalBooksInLibrary()
    
       return books;  
    


【问题讨论】:

您无法以编程方式区分组合与聚合。差异是相当哲学的。 【参考方案1】:

据我所知(也许其他人可以给出更好的答案),您无法仅通过查看 Java 代码来评估关系是聚合还是组合。反之亦然。

首先,您创建一个世界的概念模型。图书馆有书,汽车有***。然后你会想 - 在我工作的背景下,没有图书馆而存在书籍是否有意义,或者没有汽车而存在车轮是否有意义。因此,例如,如果您正在编写赛车游戏,那么您将不会使用汽车之外的***。但是,如果您正在编写一些自动修复应用程序,您将独立于某些特定汽车来处理车轮。

因此,首先您决定是否需要聚合或组合,然后在您的代码中实现它。实现可能是对象Car 具有List&lt;Wheel&gt;,但仅凭此您无法判断它是组合还是聚合。关键是你根据你的概念模型来解释代码(实现),然后根据它来使用它。

如果是组合的话,使用上可能会有一些限制:

Car 之外的任何对象都不会持有对Wheel 的引用。 Wheel 甚至可能是私有或包私有类。 如果Car保存在数据库中,当你删除它时,你也会自动删除它所有的Wheels。

但是,如果您决定它的组成,则由您来执行这些限制。

【讨论】:

【参考方案2】:

在现实世界中,一本书可以确实独立存在,而不属于图书馆。但是,如果您有一个 LibraryBook 类,其中包含 dateAcquiredcurrentBorrower 之类的字段,该怎么办?使用您的设计,您仍然可以在没有库的情况下创建 LibraryBook 实例。

这就是像 C++ 这样的语言在组合方面可以更加明确的地方:在 C++ 中,对象可以按值保存其部分。在 Java 中,每个对象都由一个指针处理(好吧,Java 人不称它们为指针;他们称它们为引用。)这使得区分组合和聚合变得更加困难。在 Java 中,您需要仔细设计。

例如,我们可以通过Library的方法使LibraryBook类只能实例化:

class Library 
    class LibraryBook 
        private LibraryBook() /*private constructor prevents independent instantiation*/
    
    LibraryBook createBook(String title, etc...);

此外,如果我们让 LibraryBook 的 mutator 方法只能由 Library 类访问,我们可以确保这本书仍然是其所属图书馆的一部分。

【讨论】:

好的..但是组合可以存在于类及其嵌套类之间,如您的示例所示,因为根据链接中的定义“关联是通过它们的对象建立的两个独立类之间的关系”和组合是协会的一部分

以上是关于以编程方式区分组合和聚合的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB: 聚合框架

Dubbo -- 系统学习 笔记 -- 示例 -- 分组聚合

数据库演练外键SQL语句的编写&分组和聚合函数的组合使用

区分单击下拉列表三角形和单击其他任何位置的组合框

reduce连接是怎么按组合键分组聚合功能原理详解

SQL语句汇总——聚合函数分组子查询及组合查询