Achtergrond:
Beide termen — compositie en aggregatie — komen uit de klassieke objectgeoriënteerde ontwerptheorie. Ze beschrijven de relaties tussen objecten: "geheel–deel", maar verschillen in de mate van afhankelijkheid tussen objecten.
Probleem:
In grote systemen is de leesbaarheid en uitbreidbaarheid van de code belangrijk. Compositie en aggregatie helpen om correcte afhankelijkheden tussen klassen te structureren. Het is belangrijk om het verschil te begrijpen — anders kan de architectuur te rigide of, omgekeerd, onduidelijk worden.
Oplossing:
Compositie is een sterke 'deel-geheel' relatie. Een object is alleen binnen een ander object aanwezig en kan niet los van het andere bestaan. In Python wordt zo'n object meestal aangemaakt en beheerd binnen de containerklasse.
Aggregatie is een zwakkere relatie. Het deel-object kan onafhankelijk van het geheel-object bestaan en van buitenaf aan het geheel worden doorgegeven.
Code voorbeeld:
class Engine: def start(self): print("Motor gestart") class Car: # Compositie: Engine wordt binnen Car aangemaakt def __init__(self): self.engine = Engine() def drive(self): self.engine.start() my_car = Car() my_car.drive() class Wheel: pass class Bicycle: # Aggregatie: wielen worden van buitenaf doorgegeven def __init__(self, wheels): self.wheels = wheels w1, w2 = Wheel(), Wheel() bike = Bicycle([w1, w2])
Belangrijke kenmerken:
Als het containerobject (bijvoorbeeld Car) wordt verwijderd, wordt dan ook het Engine-object verwijderd?
Bij compositie, als er niet langer naar het deel-object wordt verwezen, wordt het door de garbage collector verwijderd. Bij aggregatie kan het deel-object blijven bestaan (het kan door andere objecten worden verwezen).
Heeft Python speciale syntaxis voor aggregatie en compositie zoals in andere talen?
In Python zijn er geen sleutelwoorden die expliciete compositie/aggregatie aangeven. Het hangt af van de manier van aanmaken en de levenscyclus van objecten.
Kan compositie worden vervangen door aggregatie en vice versa zonder de logica opnieuw te schrijven?
Niet altijd. Als de logica volledige controle en uniciteit van het deel-object vereist, kan een eenvoudige vervanging van compositie door aggregatie leiden tot fouten (bijvoorbeeld als de wielen van verschillende fietsen gemeenschappelijke instanties van één klasse worden).
Voordelen:
Negatief geval: In een project werd er voor elk voertuig een extern motorobject aangemaakt en via aggregatie aan de auto geleverd. Uiteindelijk raakten de referenties naar de objecten verwisseld en werden de motoren willekeurig tussen auto’s gewisseld — wat leidde tot verwarring en bugs.
Voordelen: de architectuur leek flexibel. Nadelen: het was moeilijk te begrijpen welke motor bij welke auto hoorde.
Positief geval: In een ander project werden de motoren binnen de Car-klasse aangemaakt (compositie); de auto’s beheerden hun motoren rechtstreeks, wat betrouwbaarheid verzekerde.
Voordelen: geen lekken en logische verwarring. Nadelen: er moest iets meer code geschreven worden om de levenscyclus van elke auto en zijn onderdelen te beheren.