1

I'm really having a hard understanding Composition and Aggregation. In the code below, I would like to know which of the following car instance uses composition logic or aggregation logic.

public class Engine {

    public Engine() {

    }
}

public class Car1 {

    public final Engine engine;

    public Car1() {
        engine = new Engine();

    }

}

class Car2{

    public Engine engine;

    public Car2(Engine engine) {
        this.engine = engine;
    }
}

class Car3{

    public final Engine engine;

    public Car3(Engine engine) {
        this.engine = engine;
    }
}

class Car4{

       Engine engine;

       public Car4(){

        this.engine = new Engine();

       }

}


class Main{

    public static void main(String[] args) {

        Engine engine = new Engine(); 
        Car1 car1 = new Car1(); 

        Car2 car2_1 = new Car2(new Engine());
        Car2 car2_2 = new Car2(engine);

        Car3 car3_1 = new Car3(new Engine());
        Car3 car3_2 = new Car3(engine);

        Car4 car4_1 = new Car4();

    }
}

According to me, car1, car2_1, car3_1 follows Compostion logic. But I have read many places that car3_2 is also composition. Why? If we destroy car3_2 still engine instance would exist, so that should be Aggregation.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
device
  • 95
  • 6
  • Possible duplicate of [What is the difference between association, aggregation and composition?](https://stackoverflow.com/questions/885937/what-is-the-difference-between-association-aggregation-and-composition) – jaco0646 Nov 08 '19 at 15:45

3 Answers3

0

Yeah, engine still exist outside car3_2 instance, so that should be Aggregation.

Tristan
  • 43
  • 5
0

I guess in Java the differences are difficult to see as for any Object you can only store references to some heap location, whereas in other programming languages like C++ you can choose whether one object holds a reference to another object vs one object holds an embedded copy of that object.

But we are in java, and looking at the lifecycles.... Whether the engine will exist longer than the car depends if someone holds a reference to that engine. All cars but car4 have a publicly available engine field, anyone could just grab and keep the reference and thus keep the engine while throwing away the car.

I'd prefer car4 not to have a package (default) but even private access. That would mean noone should have access to that engine reference (unless that is leaked elsewhere) and you could speak about Composition.

Edit: Rereading your question and code sample to the bottom, I think the question is about how they are constructed. Car1 and car4_1 do come with their own implicitly created engines, and as noone grabs a reference the cars and the engines get garbage collected at the same time. I'd call this composition.

Car2_1 and car3_1 do behave the same although the engine got constructed explicitly. They would get garbage collected together with their respective engines. This behaves similarly but also allows the next pattern. I guess it was introduced as decoy.

Car2_2 and car3_2 both share one explicitly created engine, and the reference to it is present in the main method. The one or both of the cars could get garbage collected but the engine would stay unless all three references are given up. So this probably should show aggregation.

Queeg
  • 7,748
  • 1
  • 16
  • 42
0
  • 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. Example: House (parent) and Room (child). Rooms don't exist separate to a House.

So, by that very nature, it cannot be Composition for any object that:

  • can be owned by more than one other object
  • can be unowned (after initialization completes)
  • can change owner

car3_2 can't be Composition, since it shares the engine with car2_2.

Are all the others Composition? Logically speaking, in Real Life, you can remove the engine from a car and install it in another car, so the car-engine relationship is Aggregation.

Programmatically, the final keyword prevents removing an Engine from the Car, but it doesn't prevent the same engine from being added to another car, and it doesn't prevent the car from being "deleted" and the engine from changing owner, so final by itself doesn't ensure a Composition relationship.

When the constructor takes the engine as parameter, the Car class cannot ensure that the engine is not shared, so doesn't ensure a Composition relationship.

Only when the Engine is created by the Car constructor and the field is final (or effectively-final, essentially private with no setter method), is it guaranteed that the definition of Composition is honored.

Doesn't mean the others, which take Engine as parameter, can't effectively be composition. It depends on how it is used. E.g. if the Car is created by a Factory class, the factory can enforce the composition rules.

Andreas
  • 154,647
  • 11
  • 152
  • 247