Implementing Aggregation

Implementing Aggregation

Yesterday we considered how to implement Composition. Today we’ll do the same for Aggregation.

To recap, Aggregation is the idea of several parts working together to produce higher-level behaviour. The lifetimes of the components are not limited to the collaboration. I.e. the parts exist, collaborate to achieve some objective, and then disband. Not unlike an agile team working together to accomplish an outcome.

Aggregation becomes even more potent when we combine it with Abstraction

A particular car is an aggregation of multiple components. One of these components is a propulsion system, specifically a petrol internal combustion engine. Would our design not be that much more versatile if our car was not limited to one type of engine – ie. If it could also function with an electric engine or a Diesel motor? Yes, of course, it would. 

Aggregation and Abstraction together are the foundation of easily changeable, well-architected systems.  

Aggregation, combined with Abstraction obeys the Dependency Inversion Principle.

Let me get back on track with regards to implementing Aggregation.

Given that the aggregated components have their own lifetimes, they are instantiated outside of the collaboration.

Here is an example where five lower-level services are injected into a TransactionImportUseCase constructor so that later on in a method call they can collaborate to import bank account transactions into the system:

  public TransactionsImportUseCase(IAccountProvider accountProvider,
     ITransactionProvider transactionProvider,
     ITransactionImporter transactionImporter,
     ILocalTimeProvider localTimeProvider,
     ILogger logger)
        : base(accountProvider, transactionProvider, logger)
     {
        TransactionImporter = transactionImporter;
        LocalTimeProvider = localTimeProvider;
     }

Constructor injection is my preferred manner of introducing aggregate parts to the class orchestrating their collaboration. There are other ways, e.g. Setter injection:

  public IAccountProvider AccountProvider { get; set; }

or passing a method parameter:

  public void ImportTransactions(string accountGroupName, IAccountProvider accountProvider)

There are many ways to get various collaborators together so they can do their work.

We are coming to the end of our journey into Aggregation and Composition. Next time we’ll look at why we should (often) prefer Aggregation to Inheritance. 

A parting thought: It’s best not to get hung up on the distinction between Composition vs Aggregation. Suffice it to say that the difference is a minor one. Most of the time in our programming, we use Aggregation rather than Composition.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply