Java中聚合和组合的实现差异

Raj*_*ath 98 java composition relationship aggregation

我知道聚合和组合之间的概念差异.有人可以通过示例告诉我它们之间Java的实现差异吗?

Ana*_*and 213

组成

final class Car {

  private final Engine engine;

  Car(EngineSpecs specs) {
    engine = new Engine(specs);
  }

  void move() {
    engine.work();
  }
}
Run Code Online (Sandbox Code Playgroud)

聚合

final class Car {

  private Engine engine;

  void setEngine(Engine engine) {
    this.engine = engine;
  }

  void move() {
    if (engine != null)
      engine.work();
  }
}
Run Code Online (Sandbox Code Playgroud)

在组合的情况下,发动机完全由汽车封装.外界无法获得对引擎的引用.发动机与汽车一起生存和死亡.通过聚合,Car还可以通过引擎执行其功能,但引擎并不总是Car的内部部分.发动机可以互换,甚至完全拆除.不仅如此,外界还可以引用引擎,无论是否在车内,都可以对其进行修补.

  • 这不是一个正确的例子.外部世界可以访问内部对象,但它的身份始终与外部对象相关联,而在聚合中,即使没有汽车,内部对象也可以独立存在.在这种情况下,即使没有汽车,仍然可以使用`new Engine(EngineSpecs)`调用创建引擎.实现组合的方法是将Engine创建为内部类,以便始终参考Car对象创建引擎对象 (8认同)
  • 好例子!它还将组合显示为强关联(没有引擎时Car没有意义)和聚合作为弱关联(没有引擎的Car完全有意义,它甚至不需要构造函数中的一个).哪一个使用?取决于上下文. (6认同)

Tec*_*ter 19

我会使用一个很好的UML示例.

大学有1到20个不同的部门,每个部门有1到5个教授.大学及其部门之间有一个组合链接.部门与其教授之间存在聚合链接.

组成只是一个强大的聚合,如果大学被摧毁,那么部门也应该被销毁.但即使各自的部门消失,我们也不应该杀死教授.

在java中:

public class University {

     private List<Department> departments;

     public void destroy(){
         //it's composition, when i destroy a university I also destroy the departments. they cant live outside my university instance
         if(departments!=null)
             for(Department d : departments) d.destroy();
         departments.clean();
         departments = null;
     }
}

public class Department {

     private List<Professor> professors;
     private University university;

     Department(University univ){
         this.university = univ;
         //check here univ not null throw whatever depending on your needs
     }

     public void destroy(){
         //It's aggregation here, we just tell the professor they are fired but they can still keep living
         for(Professor p:professors)
             p.fire(this);
         professors.clean();
         professors = null;
     }
}

public class Professor {

     private String name;
     private List<Department> attachedDepartments;

     public void destroy(){

     }

     public void fire(Department d){
         attachedDepartments.remove(d);
     }
}
Run Code Online (Sandbox Code Playgroud)

这件事.


Thi*_*tha 5

一个简单的组合程序

public class Person {
    private double salary;
    private String name;
    private Birthday bday;

    public Person(int y,int m,int d,String name){
        bday=new Birthday(y, m, d);
        this.name=name;
    }


    public double getSalary() {
        return salary;
    }

    public String getName() {
        return name;
    }

    public Birthday getBday() {
        return bday;
    }

    ///////////////////////////////inner class///////////////////////
    private class Birthday{
        int year,month,day;

        public Birthday(int y,int m,int d){
            year=y;
            month=m;
            day=d;
        }

        public String toString(){
           return String.format("%s-%s-%s", year,month,day);

        }
    }

    //////////////////////////////////////////////////////////////////

}
public class CompositionTst {

    public static void main(String[] args) {
        // TODO code application logic here
        Person person=new Person(2001, 11, 29, "Thilina");
        System.out.println("Name : "+person.getName());
        System.out.println("Birthday : "+person.getBday());

        //The below object cannot be created. A bithday cannot exixts without a Person 
        //Birthday bday=new Birthday(1988,11,10);

    }
}
Run Code Online (Sandbox Code Playgroud)


Kvk*_*Kvk 5

简单来说 :

组合和聚合都是关联。组合 -> 强 Has-A 关系 聚合 -> 弱 Has-A 关系。


mic*_*oon 5

首先,我们必须讨论Aggregation和之间的实际区别Composition是什么。

聚合是一种关联,其中关联的实体可以独立于关联而存在。例如,一个人可能与一个组织相关联,但他/她可能在系统中独立存在。

然而

组合是指其中一个关联实体与另一个实体强相关并且没有另一个实体就无法存在的情况。事实上,该实体的身份始终与其他对象的身份相关联。例如,汽车的轮子。

现在,可以通过在另一个实体中保存一个实体的属性来简单地实现聚合,如下所示:

class Person {
    Organisation worksFor;
}

class Organisation {
    String name;
}

class Main {
    public static void main(String args[]) {

        //Create Person object independently
        Person p = new Person();

        //Create the Organisation independently
        Organisation o = new Organisation();
        o.name = "XYZ Corporation";

        /*
          At this point both person and organisation 
          exist without any association  
        */
        p.worksFor = o;

    }
}
Run Code Online (Sandbox Code Playgroud)

对于组合,必须始终使用其关联对象的标识来创建依赖对象。您可以使用内部类来实现相同的目的。

class Car {
    class Wheel {
        Car associatedWith;
    }
}

class Main {
    public static void main() {
        //Create Car object independently
        Car car = new Car();

        //Cannot create Wheel instance independently
        //need a reference of a Car for the same.
        Car.Wheel wheel = car.new Wheel();
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,根据应用场景,相同的用例可能属于聚合/组合。例如,如果您正在为在某个组织中工作的人员开发应用程序,并且注册时必须引用组织,则“个人-组织”案例可能会变成组合。同样,如果您要维护汽车零件的库存,则汽车与车轮的关系可以是聚合。