Validierungslogik
Teil des Abschnitts Objektorientierte Programmierung der Lua-Journey von Coddy. Lektion 47 von 70.
Bisher haben wir verschiedene Möglichkeiten zum Schutz von Daten untersucht: Namenskonventionen signalisieren die Absicht, Closures verbergen Variablen vollständig, und schreibgeschützte Tabellen verhindern alle Änderungen. Oft braucht man jedoch etwas dazwischen: Änderungen zuzulassen, aber nur gültige.
Hier zeigen sich die Vorteile von Setter-Methoden. Anstatt nur einen Wert zuzuweisen, kann ein Setter überprüfen, ob der neue Wert sinnvoll ist, bevor er ihn akzeptiert:
local Person = {}
Person.__index = Person
function Person:new(name, age)
local obj = {
_name = name,
_age = age
}
setmetatable(obj, Person)
return obj
end
function Person:setAge(newAge)
if newAge < 0 then
print("Error: Age cannot be negative")
return
end
self._age = newAge
endWenn jemand person:setAge(-5) aufruft, fängt die Methode die ungültige Eingabe ab und verweigert die Aktualisierung. Der Zustand des Objekts bleibt konsistent. Ohne diesen Schutz könnten fehlerhafte Daten dein Programm unbemerkt beschädigen: Stell dir vor, du berechnest Altersvorsorgeleistungen mit einem negativen Alter.
Die Validierung kann so einfach oder komplex sein wie nötig. Du könntest Bereiche prüfen, Typen überprüfen oder sicherstellen, dass Werte den erwarteten Formaten entsprechen. Das zentrale Prinzip besteht darin, dass der Setter als Torwächter fungiert und sicherstellt, dass nur sinnvolle Daten in dein Objekt gelangen.
Aufgabe
EinfachErstellen wir eine Player-Klasse, die ihre Attribute für Gesundheit und Level mithilfe von Validierungslogik in Setter-Methoden schützt! Dadurch wird sichergestellt, dass Spielcharaktere niemals unmögliche Werte erhalten.
Du organisierst deinen Code auf zwei Dateien:
Player.lua: Erstelle eine Klasse, die die Werte eines Spielers mit geeigneter Validierung verwaltet. Der Konstruktor:new(name)soll den Spieler mit einem Namen initialisieren,_healthauf100und_levelauf1setzen. Füge diese Methoden hinzu::getName(): gibt den Namen des Spielers zurück:getHealth(): gibt die aktuelle Gesundheit zurück:getLevel(): gibt das aktuelle Level zurück:setHealth(value): aktualisiert die Gesundheit nur, wenn der Wert zwischen 0 und 100 (einschließlich) liegt. Wenn der Wert ungültig ist, gibError: Health must be between 0 and 100aus und ändere den Wert nicht.:setLevel(value): aktualisiert das Level nur, wenn der Wert mindestens 1 beträgt. Wenn der Wert ungültig ist, gibError: Level must be at least 1aus und ändere den Wert nicht.
main.lua: Binde dein Player-Modul ein und lies einen Spielernamen und anschließend zwei Werte ein, um die Setter zu testen. Erstelle einen Spieler, versuche, seine Gesundheit auf den ersten Wert zu setzen, versuche, sein Level auf den zweiten Wert zu setzen, und gib anschließend die endgültigen Werte des Spielers aus.
Du erhältst drei Eingaben:
- Den Namen des Spielers
- Einen Gesundheitswert, der gesetzt werden soll (eine Zahl, die gültig oder ungültig sein kann)
- Einen Levelwert, der gesetzt werden soll (eine Zahl, die gültig oder ungültig sein kann)
Deine Ausgabe soll alle Fehlermeldungen ungültiger Versuche anzeigen, gefolgt von den endgültigen Werten des Spielers:
Name: {name}
Health: {finalHealth}
Level: {finalLevel}Wenn die Eingaben beispielsweise Hero, -20 und 5 lauten, soll die Ausgabe folgendermaßen aussehen:
Error: Health must be between 0 and 100
Name: Hero
Health: 100
Level: 5Der Setter für die Gesundheit hat -20 abgelehnt (die Gesundheit blieb bei 100), während der Setter für das Level 5 als gültigen Wert akzeptiert hat.
Wenn die Eingaben Warrior, 75 und 0 lauten, soll die Ausgabe folgendermaßen aussehen:
Error: Level must be at least 1
Name: Warrior
Health: 75
Level: 1Probier es selbst
-- Lade das Player-Modul
local Player = require('Player')
-- Eingaben lesen
local name = io.read()
local healthValue = tonumber(io.read())
local levelValue = tonumber(io.read())
-- TODO: Erstelle einen neuen Player mit dem gegebenen Namen
-- TODO: Versuche, die Gesundheit des Players auf healthValue zu setzen
-- TODO: Versuche, das Level des Players auf levelValue zu setzen
-- TODO: Gib die finalen Stats des Players im Format aus:
-- Name: {name}
-- Health: {finalHealth}
-- Level: {finalLevel}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
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-KlasseKreis-KlasseUmfang-MethodeFormen-SammlungGesamtflächeFormen filtern2Klassen-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Übe selbstständig: Online-Lua-Compiler