Delegated verantwoordelijkheid via compositie is een programmeerpraktijk waarbij een object van een klasse een object van een andere klasse (of klassen) bevat en deze gebruikt om een deel van zijn logica te implementeren, in plaats van hun interface te erven.
Vroege versies van OOP legden de nadruk op overerving, maar na verloop van tijd heeft de praktijk aangetoond dat compositie vaak meer flexibiliteit, uitbreidbaarheid en vermindering van afhankelijkheid tussen componenten biedt.
Overerving bindt objecten sterk: veranderingen in de basisklasse hebben invloed op alle afgeleiden, hiërarchieën worden complex en de architectuur kan kwetsbaar zijn. Compositie verhelpt deze problemen, waardoor betrouwbaardere en gemakkelijker te onderhouden systemen kunnen worden gebouwd.
In C++ wordt delegatie geïmplementeerd door een object van de ene klasse als lid van de andere klasse op te nemen. In de wrapper-klasse worden de methoden van het geneste object aangeroepen.
Voorbeeldcode:
class Logger { public: void log(const std::string& msg) { std::cout << msg << std::endl; } }; class FileProcessor { Logger logger; // Compositie public: void process(const std::string& filename) { logger.log("Processing file: " + filename); // ... } };
Belangrijke kenmerken:
Kan compositie volledig overerving vervangen?
Nee, overerving is nodig waar een "is-a" relatie vereist is, compositie waar een "has-a" relatie nodig is. Bijvoorbeeld, Button erft van Widget, maar Car "heeft" Engine (compositie).
Kan het gedrag van de gedelegeerde methode in compositie worden gewijzigd?
Ja, delegatiemethoden kunnen worden aangepast zonder de oorspronkelijke klasse aan te raken. Daarnaast kan het gedelegeerde object dynamisch worden gewijzigd (bijvoorbeeld via een pointer of unieke pointer).
Is compositie langzamer dan overerving?
Nee, er is in de meeste gevallen geen prestatieverschil. Soms kan overerving extra kosten met zich meebrengen door virtuele aanroepen (vtable), terwijl compositie alleen de grootte van het object toevoegt.
In het project erfden alle dialoogvensters van een algemene DialogWindow. Het toevoegen van nieuwe businesslogica leidde tot niet-werkende code in alle afgeleiden.
Voordelen:
Nadelen:
Algemene functies zijn ondergebracht in aparte klassen (logging, validatie), die in elk dialoogvenster via compositie worden geïmplementeerd.
Voordelen:
Nadelen: