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

时间:2018-05-01 08:19:34

标签: java oop aggregation composition

我正在通过以下链接来确定组合和聚合之间的区别。

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

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

聚合

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

}

2 个答案:

答案 0 :(得分:4)

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

首先,您要创建一个世界概念模型。图书馆有书,车有轮子。那么你认为 - 没有一个图书馆存在一本书,或者没有汽车就存在一个轮子,在我工作的环境中是否有意义。因此,例如,如果您正在编写赛车游戏,您将无法使用汽车外的车轮。但是如果你正在编写一些自动修复应用程序,你将独立于一些特定的汽车处理轮子。

首先,您决定是否需要聚合或组合,然后在代码中实现它。实现可能是对象Car具有List<Wheel>,但您无法通过它来判断它的组成或聚合。关键是你根据概念模型解释代码(实现),然后根据它使用它。

如果它的构成,它的使用可能有一些限制:

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

但是如果你决定了这些限制,那么你可以强制执行这些限制。

答案 1 :(得分:0)

在现实世界中,一本书可以确实存在,而不是由图书馆拥有。但是,如果您的LibraryBook课程包含dateAcquiredcurrentBorrower等字段,该怎么办?使用您的设计,您仍然可以创建没有库的LibraryBook实例。

这就是像C ++这样的语言可以更明确地表达组合:在C ++中,对象可以按值保存其部分。在Java中,每个对象都由一个指针处理(好吧,Java人们不会将它们称为指针;而是将它们称为引用。)这使得区分组合和聚合变得更加困难。在Java中,您可以使用精心设计来完成它。

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

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

此外,如果我们只使LibraryBook的mutator方法可以访问Library类,我们可以确保该书仍然是其拥有的库的一部分。