Composition And Aggregation

Composition And Aggregation

 

In OOP programming, one hears that ‘Composition is better than Inheritance‘. Why? And is it always true? To answer these questions, we will first explore how Composition, and a closely related concept, Aggregation, work. 

Let’s first consider what Composition and Aggregation have in common: Both are parent-child relationships. However, unlike with Inheritance, a child is not a specialised version of the parent. With Aggregation and Composition, a child is part of a parent. Several different child-parts will make up the parent. The parent is composed of its children. 

An example is in order.

With Inheritance, the parent is, say, the Engine class. The child or subclass versions will be specialised versions of Engine: PetrolEngine, ElectricEngine, NuclearEngine, and so on.

Let’s carry on with the Engine example for Aggregation and Composition. An ElectricEngine class might be made up of Magnets, Wire, Brushes, etc.. And PetrolEngine will be composed of Pistons, FuelInjection, SparkPlugs and other parts.  

And the difference between Aggregation and Composition?

Use Composition to model scenarios where the component parts do not exist independently from the parent. Pistons are not much use other than in a PetrolEngine. Therefore we should prefer Composition to model our PetrolEngine in OO code.

Aggregation is a looser relationship between parent and children: Children can exist outside of the parent. For example, Student (child) exists independently from Course (parent).

How might we model these differences in code?

Aggregation:

  public class Course
  {
     private IList<Student> Students { get; } = new List<Student>();

     public void Add(Student student)
     {
        Students.Add(student);
     }
  }

With Aggregation, the Student class may exist independently from the Course. Therefore it is acceptable for the Student instance to be created outside of the Course and then passed into it via the Add() method.

Composition:

  public class PetrolEngine
  {
     private IList<Piston> Pistons { get; } = new List<Piston>();

     public Course(int numberOfPistons = 4)
     {
        for (var i = 0; i < numberOfPistons; i++)
           Pistons.Add(new Piston());
     }
  }

For Composition, Pistons only make sense within the PetrolEngine. PetrolEngine internally instantiates the required number of Pistons. Or in other words, if Pistons do not make sense by themselves, then they should not be instantiated and passed into PetrolEngine. Doing so would imply that we can create and use the Piston class outside of PetrolEngine.

Question: Is there some way for us to structure the code so that Pistons can only be instantiated and used within the PetrolEngine class? I.e. we get a compilation error if we try to use Piston outside of PetrolEngine?

Until tomorrow when I will reveal the answer.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply