Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementation difference between Aggregation and Composition in Java

I'm aware of the conceptual differences between Aggregation and Composition. Can someone tell me the implementation difference in Java between them with examples?

like image 338
Rajath Avatar asked Aug 09 '12 10:08

Rajath


People also ask

What is the difference between the implementations of a composition and an Aggregation?

Aggregation implies a relationship where the child can exist independently of the parent. For example, Bank and Employee, delete the Bank and the Employee still exist. whereas Composition implies a relationship where the child cannot exist independent of the parent.

How does composition differ from Aggregation in Java?

The only difference between Aggregation and Composition is that in Aggregation, objects are not tightly coupled or don't involve owning. All the objects are independent of each other and can exist even if the parent object gets deleted.

What are the differences between composition and Aggregation explain with example?

Aggregation implies a relationship where the child can exist independently of the parent. Example: Class (parent) and Student (child). Delete the Class and the Students still exist. Composition implies a relationship where the child cannot exist independent of the parent.


2 Answers

Composition

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

Aggregation

final class Car {    private Engine engine;    void setEngine(Engine engine) {     this.engine = engine;   }    void move() {     if (engine != null)       engine.work();   } } 

In the case of composition, the Engine is completely encapsulated by the Car. There is no way for the outside world to get a reference to the Engine. The Engine lives and dies with the car. With aggregation, the Car also performs its functions through an Engine, but the Engine is not always an internal part of the Car. Engines may be swapped, or even completely removed. Not only that, but the outside world can still have a reference to the Engine, and tinker with it regardless of whether it's in the Car.

like image 84
Anand Avatar answered Oct 13 '22 01:10

Anand


I would use a nice UML example.

Take a university that has 1 to 20 different departments and each department has 1 to 5 professors. There is a composition link between a University and its' departments. There is an aggregation link between a department and its' professors.

Composition is just a STRONG aggregation, if the university is destroyed then the departments should also be destroyed. But we shouldn't kill the professors even if their respective departments disappear.

In 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);      } } 

Something around this.

EDIT: an example as requested

public class Test {     public static void main(String[] args)     {         University university = new University();         //the department only exists in the university         Department dep = university.createDepartment();         // the professor exists outside the university         Professor prof = new Professor("Raoul");         System.out.println(university.toString());         System.out.println(prof.toString());          dep.assign(prof);         System.out.println(university.toString());         System.out.println(prof.toString());         dep.destroy();          System.out.println(university.toString());         System.out.println(prof.toString());      }   } 

University class

import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors;  public class University {      private List<Department> departments = new ArrayList<>();      public Department createDepartment() {         final Department dep = new Department(this, "Math");         departments.add(dep);         return dep;     }      public void destroy() {         System.out.println("Destroying university");         //it's composition, when I destroy a university I also destroy the departments. they cant live outside my university instance         if (departments != null)             departments.forEach(Department::destroy);         departments = null;     }      @Override     public String toString() {         return "University{\n" +                 "departments=\n" + departments.stream().map(Department::toString).collect(Collectors.joining("\n")) +                 "\n}";     } } 

Department class

import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors;  public class Department {      private final String name;     private List<Professor> professors = new ArrayList<>();     private final University university;      public Department(University univ, String name) {         this.university = univ;         this.name = name;         //check here univ not null throw whatever depending on your needs     }      public void assign(Professor p) {         //maybe use a Set here         System.out.println("Department hiring " + p.getName());         professors.add(p);         p.join(this);     }      public void fire(Professor p) {         //maybe use a Set here         System.out.println("Department firing " + p.getName());         professors.remove(p);         p.quit(this);     }      public void destroy() {         //It's aggregation here, we just tell the professor they are fired but they can still keep living         System.out.println("Destroying department");         professors.forEach(professor -> professor.quit(this));         professors = null;     }      @Override     public String toString() {         return professors == null                 ? "Department " + name + " doesn't exists anymore"                 : "Department " + name + "{\n" +                 "professors=" + professors.stream().map(Professor::toString).collect(Collectors.joining("\n")) +                 "\n}";     } } 

Professor class

import java.util.ArrayList; import java.util.List;  public class Professor {      private final String name;     private final List<Department> attachedDepartments = new ArrayList<>();      public Professor(String name) {         this.name = name;     }      public void destroy() {      }      public void join(Department d) {         attachedDepartments.add(d);     }      public void quit(Department d) {         attachedDepartments.remove(d);     }      public String getName() {         return name;     }      @Override     public String toString() {         return "Professor " + name + " working for " + attachedDepartments.size() + " department(s)\n";     } } 

The implementation is debatable as it depends on how you need to handle creation, hiring deletion etc. Unrelevant for the OP

like image 23
TecHunter Avatar answered Oct 13 '22 00:10

TecHunter