Delegierung von Verantwortung durch Komposition ist eine Programmierpraxis, bei der ein Objekt einer Klasse ein Objekt einer anderen Klasse (oder Klassen) enthält und diese zur Umsetzung eines Teils seiner Logik nutzt, anstatt deren Schnittstelle zu erben.
Frühere Versionen der OOP legten den Fokus auf Vererbung, aber im Laufe der Zeit hat sich gezeigt, dass Komposition oft größere Flexibilität, Erweiterbarkeit und eine geringere Verknüpfung zwischen Komponenten bietet.
Vererbung verknüpft Objekte fest: Änderungen in der Basisklasse betreffen alle Erben, Hierarchien werden komplex, was die Architektur fragil macht. Komposition löst diese Probleme, ermöglicht den Aufbau von zuverlässigeren und wartbareren Systemen.
In C++ wird Delegierung durch die Einbindung eines Objekts einer Klasse als Mitglied einer anderen Klasse realisiert. In der Wrapper-Klasse werden die Methoden des eingebetteten Objekts aufgerufen.
Beispielcode:
class Logger { public: void log(const std::string& msg) { std::cout << msg << std::endl; } }; class FileProcessor { Logger logger; // Komposition public: void process(const std::string& filename) { logger.log("Verarbeite Datei: " + filename); // ... } };
Wesentliche Merkmale:
Kann Komposition die Vererbung vollständig ersetzen?
Nein, Vererbung ist notwendig, wo eine "ist-ein" (is-a) Beziehung erforderlich ist, Komposition — wo "hat-ein" (has-a) vorliegt. Zum Beispiel erbt Button von Widget, aber Car "hat" Engine (Komposition).
Kann das Verhalten der delegierten Methode in der Komposition geändert werden?
Ja, die Delegierungsmethoden können angepasst werden, ohne die ursprüngliche Klasse zu berühren. Auch das delegierte Objekt kann dynamisch geändert werden (zum Beispiel über einen Zeiger oder einen einzigartigen Zeiger).
Ist Komposition langsamer als Vererbung?
Nein, es gibt in den meisten Fällen keinen Unterschied in der Leistung. Manchmal fügt Vererbung Kosten durch virtuelle Aufrufe (vtable) hinzu, während Komposition nur die Größe des Objekts betrifft.
In dem Projekt erbten alle Dialogfenster von einem gemeinsamen Dialogfenster. Das Hinzufügen neuer Geschäftslogik führte zu fehlerhaftem Code in allen Erben.
Vorteile:
Nachteile:
Allgemeine Funktionen wurden in separate Klassen (Logging, Validierung) ausgelagert, die in jeden Dialog durch Komposition eingefügt werden.
Vorteile:
Nachteile: