Composition over Inheritance

Eerst even back to the basics. Wat wordt bedoeld met overerving en wat wordt bedoeld met composition. Als je het zou moeten beschrijven dan spreek je bij overerving van een 'is-een' relatie en bij composition heb je het over een 'is-een-onderdeel-van' relatie. In code ziet overerving er zo uit:

public class Vehicle
{
  
}

public class Car : Vehicle
{

}

Er is hier duidelijk sprake van de 'is-een' relatie: Een auto is een voertuig. Bij composition ziet de code er als volgt uit:

public class Engine
{

}

// Possibility 1: Create the 'composition' inside the constructor
public class Car
{
  private readonly Engine _engine;

  public Car()
  {
    _engine = new Engine();
  }
}

// Possibility 2: Inject the 'composition' in the constructor using Dependency Injection (DI).
public class Car
{
  private readonly Engine _engine;

  public Car()
  {
    _engine = new Engine();
  }
}

In dit voorbeeld zie je dat een Engine onderdeel is van een auto.

Maar wanneer gebruik je nou wat? Er wordt wel gezegd 'Geef de voorkeur aan composition omdat je op deze manier runtime het gedrag kan aanpassen, maar gebruik dit niet altijd'. Lekker duidelijk: gebruik het wel, maar niet altijd. Tijd voor wat opheldering.

Zoals gezegd kan je bij composition d.m.v. Dependency Injection eenvoudig het gedrag runtime aanpassen. Bij overerving is meer rigide omdat je in C# maar van één klasse kan overerven. Je bent bij overerving dus al 'gedoemd' omdat hard-coded is besloten dat er wordt overerft van een bepaalde klasse.

Bij deze voor beide strategieën een richtlijn om te bepalen voor welke strategie je moet gaan:

Overerving:
Is het nodig / van toepassing dat alle public methods/properties van Type A ook public moeten zijn bij Type B? Ofwel, kan Type B overal gebruikt worden waar nu ook Type A gebruikt wordt? Zijn type A en B uitwisselbaar? Zo ja, dan kies je voor overerving.

Voorbeeld:
Een Cessna dubbeldekker vliegtuig heeft alle eigenschappen van een vliegtuig, zo niet meer. Dit maakt het een geldige reden om te ervan van Vliegtuig.

Composition:
Heeft Type B enkel bepaalde onderdelen nodig van Type A? Dan gebruik je composition.

Voorbeeld: Een vogel kent enkel het vlieggedrag van een vliegtuig. In dit geval is het logisch om een Vliegtuig lid te maken van de Vogel klasse, zodat Vogel zelf de Vlieg-methode van de Vliegtuig kan aanspreken.

Reacties

Populaire posts van deze blog

[SQL Server] varchar vs nvarchar

MS Sql 70-461: Chapter 5

[C#] Class serialiseren en deserialiseren