Delegation
Teil des Abschnitts Object Oriented Programming der Lua-Journey von Coddy — Lektion 50 von 70.
Das Speichern eines Objekts innerhalb eines anderen Objekts ist nur der erste Schritt. Die wahre Stärke der Komposition kommt von der Delegation – wenn das äußere Objekt Methodenaufrufe an seine inneren Komponenten weiterleitet.
Stellen Sie sich vor, Sie starten ein Auto. Sie greifen nicht unter die Motorhaube und drehen den Motor manuell an. Stattdessen drehen Sie den Schlüssel um, und das Auto erledigt den Rest intern.
Im Code bedeutet dies, dass die Car-Klasse eine einfache :start()-Methode bereitstellt, die die eigentliche Arbeit an den Motor delegiert:
function Car:start()
print("Turning the key...")
self.engine:run() -- Delegieren an das innere Objekt
endDas Auto muss nicht wissen, wie der Motor läuft—es weist den Motor lediglich an, seine Arbeit zu erledigen. Dies hält die Verantwortlichkeiten getrennt. Die Klasse Engine verarbeitet die Motorlogik, während Car die Teile koordiniert:
function Engine:run()
print("Engine running at " .. self.horsepower .. " HP")
end
local engine = Engine:new(250)
local car = Car:new("Coupe", engine)
car:start()
-- Ausgabe:
-- Schlüssel wird gedreht...
-- Motor läuft mit 250 HPDelegation schafft eine saubere Schnittstelle für Benutzer Ihrer Klasse. Sie interagieren mit dem Auto, nicht mit seinen internen Teilen. Wenn Sie später eine andere Motor-Implementierung einsetzen, bleibt die öffentliche Schnittstelle des Autos gleich – nur die interne Delegation ändert sich.
Aufgabe
EinfachLass uns ein Musik-Player-System bauen, das Delegation demonstriert! Du wirst eine Speaker-Komponente und einen MusicPlayer erstellen, der diese enthält. Der Player wird die Soundausgabe nicht direkt handhaben – stattdessen wird er diese Verantwortung an seinen internen Lautsprecher delegieren.
Du wirst deinen Code in drei Dateien organisieren:
Speaker.lua: Erstelle eine Speaker-Klasse mit einem Konstruktor:new(volume), der die Lautstärke speichert. Füge eine:playSound(trackName)-Methode hinzu, die Folgendes ausgibt:Playing "{trackName}" at volume {volume}MusicPlayer.lua: Erstelle eine MusicPlayer-Klasse, deren Konstruktor:new(brand, speaker)einen Markennamen und ein Speaker-Objekt akzeptiert. Der Player speichert den Lautsprecher in sich selbst. Füge diese Methoden hinzu::play(trackName)— gibt{brand} player starting...aus und delegiert dann an die:playSound()-Methode des Lautsprechers:stop()— gibt{brand} player stoppedaus
main.lua: Bring alles zusammen! Lies die Eingaben für die Lautsprecherlautstärke, die Player-Marke und einen Tracknamen ein. Erstelle zuerst einen Speaker und übergib ihn dann an den MusicPlayer-Konstruktor. Rufe die:play()-Methode des Players mit dem Tracknamen auf und rufe anschließend:stop()auf.
Du wirst drei Eingaben erhalten:
- Die Lautsprecherlautstärke (eine Zahl)
- Die Marke des Musik-Players (ein String)
- Der Name des zu spielenden Tracks (ein String)
Deine Ausgabe sollte zeigen, wie der Player mit seinem Lautsprecher koordiniert:
{brand} player starting...
Playing "{trackName}" at volume {volume}
{brand} player stoppedWenn die Eingaben zum Beispiel 75, SoundMax und Summer Vibes sind, sollte die Ausgabe wie folgt aussehen:
SoundMax player starting...
Playing "Summer Vibes" at volume 75
SoundMax player stoppedBeachte, dass der MusicPlayer nicht weiß, wie man Sound erzeugt – er weist einfach seinen Lautsprecher an, diesen Teil zu übernehmen. Das ist Delegation in Aktion: Das äußere Objekt bietet eine saubere Schnittstelle, während die innere Komponente die spezialisierte Arbeit erledigt!
Spickzettel
Delegation ermöglicht es einem äußeren Objekt, Methodenaufrufe an seine inneren Komponenten weiterzuleiten, wodurch Verantwortlichkeiten getrennt bleiben und saubere Schnittstellen entstehen.
Das äußere Objekt stellt einfache Methoden bereit, die die Arbeit an innere Objekte delegieren:
function Car:start()
print("Turning the key...")
self.engine:run() -- An das innere Objekt delegieren
endDas innere Objekt verarbeitet seine eigene spezialisierte Logik:
function Engine:run()
print("Engine running at " .. self.horsepower .. " HP")
end
local engine = Engine:new(250)
local car = Car:new("Coupe", engine)
car:start()
-- Ausgabe:
-- Turning the key...
-- Engine running at 250 HPVorteile der Delegation:
- Die äußere Klasse muss nicht wissen, wie das innere Objekt funktioniert
- Benutzer interagieren mit einer sauberen öffentlichen Schnittstelle
- Interne Implementierungen können ausgetauscht werden, ohne die öffentliche Schnittstelle zu ändern
Probier es selbst
-- main.lua
-- Alles zusammenführen!
local Speaker = require('Speaker')
local MusicPlayer = require('MusicPlayer')
-- Eingaben einlesen
local volume = tonumber(io.read())
local brand = io.read()
local trackName = io.read()
-- TODO: Erstelle einen Speaker mit der angegebenen volume
-- TODO: Erstelle einen MusicPlayer mit brand und speaker
-- TODO: Rufe die play-Methode des Players mit dem trackName auf
-- TODO: Rufe die stop-Methode des Players auf
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Object Oriented Programming
1Das 'self'-Konzept
Tabellen mit FunktionenExplizites 'self'Die Doppelpunkt-SyntaxPunkt vs. DoppelpunktZusammenfassung – Beweglicher Punkt4Projekt: Digitale Bank
Projekt-SetupEinzahlungsmethode7Polymorphie & Überschreiben
Methoden überschreibenElternmethoden aufrufenDuck TypingGemeinsames InterfaceTyp prüfenRückblick - Mitarbeiterrollen10Projekt: Formen-Manager
Projekt-SetupRechteck-Klasse2Klassen-Prototyp-Muster
Das Prototyp-KonzeptVerknüpfung mit __indexDer :new()-KonstruktorAttribute initialisierenUnabhängige InstanzenZusammenfassung – Autofabrik5Operatorüberladung in OOP
Objekte addierenObjekte subtrahierenObjekte verkettenObjekte vergleichen (<, >)Rückblick – Wallet-Mathematik3Objektzustand und -verhalten
InstanzvariablenGetter-MethodenSetter-MethodenBerechnete EigenschaftenStrings formatierenGleichheitsprüfungenZusammenfassung – Studentennote6Grundlagen der Vererbung
Das Vererbungs-SetupMethoden vererbenDen Konstruktor erweiternChild-Methoden hinzufügenGemeinsam vs. EinzigartigZusammenfassung - Formen-Hierarchie9Komposition & Mixins
Has-A-BeziehungDelegationEinfache MixinsAnwendung mehrerer MixinsMixins vs. VererbungZusammenfassung – Roboter-Montage12Abschluss-Herausforderungen
Wiederholung - InventarsystemWiederholung - BenutzerverwaltungWiederholung - Score-TrackerFinaler OOP-Check