Implementation Difference Between Aggregation and Composition in Java

Implementation difference between Aggregation and Composition in Java

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.

Aggregation versus Composition

The distinction between aggregation and composition depends on context.

Take the car example mentioned in another answer - yes, it is true that a car exhaust can stand "on its own" so may not be in composition with a car - but it depends on the application. If you build an application that actually has to deal with stand alone car exhausts (a car shop management application?), aggregation would be your choice. But if this is a simple racing game and the car exhaust only serves as part of a car - well, composition would be quite fine.

Chess board? Same problem. A chess piece doesn't exist without a chess board only in certain applications. In others (like that of a toy manufacturer), a chess piece can surely not be composed into a chess board.

Things get even worse when trying to map composition/aggregation to your favorite programming language. In some languages, the difference can be easier to notice ("by reference" vs. "by value", when things are simple) but in others may not exist at all.

And one last word of advice? Don't waste too much time on this issue. It isn't worth it. The distinction is hardly useful in practice (even if you have a completely clear "composition", you may still want to implement it as an aggregation due to technical reasons - for example, caching).

The difference between Aggregation and Association in implementation

I agree that from the implementation point of view both association and aggregation look the same - like you mentioned, in both cases one of the objects is a data member in the other.

The way I understand this is that the implementation difference that you are asking about does not happen at the level of the object, but rather at the level of the application design:

  • If by implementation difference you understand the code itself (the way the object is placed within another), then there is no difference.

  • But if we extend the conversation to how the objects are used within the application, then we need to start looking at whether the objects are self sufficient or not, whether they can serve a unique, independent function or not. It is for you to decide whether this is still implementation

Edit -> additional explanation added below:

I might have not been clear enough - what I meant was that in this case the implementation could be considered on two levels:

  • the code that represents the object within the class (the field holding the reference to the object)

  • the wider code (how the object is used in other classes or how the dependencies between objects are represented)

Both of those could be understood as implementation, but on different levels of abstraction - the usage within the class is the same for both Aggregation and Composition, yet the way the object relationships are implemented across multiple classes would differ.

Differentiating Composition and Aggregation programmatically

As far as I can tell (and maybe somebody else can give a better answer), you can't evaluate if the relationship is aggregation or composition just by looking at Java code. It's the other way around.

First you create a conceptual model of the world. Libraries have books, and cars have wheels. Then you think - does it make sense for a book to exist without a library, or for a wheel to exist without a car, in the context I'm working in. So for example if you are writing a car racing game, you will have no use of wheels outside of cars. But if you are writing some auto-repair application, you will deal with wheels independently of some particular car.

So first you decide if you need aggregation or composition, and then implement it in your code. The implementation could be that object Car has List<Wheel> but you can't tell if it's composition or aggregation just from that. The key is that you interpret the code (implementation) based on your conceptual model and then use it according to that.

If it's composition, the usage it might have some restrictions:

  • No object other than Car will hold a reference to Wheel.
  • Wheel might even be a private or package-private class.
  • If Car is saved in database, when you delete it, you also automatically delete all of its Wheels.

But it's up to you to enforce these restrictions if you decide it's composition.

Difference between dependency and composition?

The difference can be seen in the two constructors:

  • Dependency: The Address object comes from outside, it's allocated somewhere else. This means that the Address and Employee objects exists separately, and only depend on each other.

  • Composition: Here you see that a new Engine is created inside Car. The Engine object is part of the Car. This means that a Car is composed of an Engine.



Related Topics



Leave a reply



Submit