Menu
Coddy logo textTech

Logica di convalida

Fa parte della sezione Programmazione orientata agli oggetti del percorso Lua di Coddy. Lezione 47 di 70.

Finora abbiamo esplorato diversi modi per proteggere i dati: le convenzioni di denominazione segnalano l’intento, le chiusure nascondono completamente le variabili e le tabelle di sola lettura impediscono qualsiasi modifica. Ma spesso serve una via di mezzo: consentire le modifiche, ma solo quelle valide.

È qui che i metodi setter diventano potenti. Invece di limitarsi ad assegnare un valore, un setter può verificare se il nuovo valore è sensato prima di accettarlo:

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
end

Quando qualcuno chiama person:setAge(-5), il metodo intercetta l'input non valido e rifiuta di aggiornare. Lo stato dell'oggetto rimane coerente. Senza questa protezione, dati errati potrebbero corrompere silenziosamente il tuo programma: immagina di calcolare i benefici pensionistici con un'età negativa.

La convalida può essere semplice o complessa, a seconda delle necessità. Potresti controllare gli intervalli, verificare i tipi o assicurarti che i valori corrispondano ai formati previsti. Il principio fondamentale è che il setter funge da guardiano, assicurandosi che nel tuo oggetto entrino solo dati sensati.

challenge icon

Sfida

Facile

Creiamo una classe Player che protegga gli attributi health e level usando la logica di convalida nei metodi setter! In questo modo i personaggi del gioco non potranno mai ritrovarsi con statistiche impossibili.

Organizzerai il codice in due file:

  • Player.lua: crea una classe che gestisca le statistiche di un giocatore con una convalida appropriata. Il costruttore :new(name) dovrebbe inizializzare il giocatore con un nome, _health impostato a 100 e _level impostato a 1. Includi questi metodi:
    • :getName(): restituisce il nome del giocatore
    • :getHealth(): restituisce la salute attuale
    • :getLevel(): restituisce il livello attuale
    • :setHealth(value): aggiorna la salute solo se il valore è compreso tra 0 e 100 (inclusi). Se non è valido, stampa Error: Health must be between 0 and 100 e non modificare il valore.
    • :setLevel(value): aggiorna il livello solo se il valore è pari o superiore a 1. Se non è valido, stampa Error: Level must be at least 1 e non modificare il valore.
  • main.lua: importa il modulo Player e leggi il nome di un giocatore, poi due valori per provare i setter. Crea un giocatore, prova a impostare la sua salute al primo valore, prova a impostare il suo livello al secondo valore, quindi stampa le statistiche finali del giocatore.

Riceverai tre input:

  1. Il nome del giocatore
  2. Un valore di salute da provare a impostare (un numero, che può essere valido o non valido)
  3. Un valore di livello da provare a impostare (un numero, che può essere valido o non valido)

L'output dovrebbe mostrare eventuali messaggi di errore relativi ai tentativi non validi, seguiti dalle statistiche finali del giocatore:

Name: {name}
Health: {finalHealth}
Level: {finalLevel}

Per esempio, se gli input sono Hero, -20 e 5, l'output dovrebbe essere:

Error: Health must be between 0 and 100
Name: Hero
Health: 100
Level: 5

Il setter della salute ha rifiutato -20 (mantenendo la salute a 100), mentre il setter del livello ha accettato 5 come valore valido.

Se gli input sono Warrior, 75 e 0, l'output dovrebbe essere:

Error: Level must be at least 1
Name: Warrior
Health: 75
Level: 1

Provalo tu

-- Importa il modulo Player
local Player = require('Player')

-- Leggi gli input
local name = io.read()
local healthValue = tonumber(io.read())
local levelValue = tonumber(io.read())

-- TODO: Crea un nuovo giocatore con il nome fornito

-- TODO: Prova a impostare la salute del giocatore su healthValue

-- TODO: Prova a impostare il livello del giocatore su levelValue

-- TODO: Stampa le statistiche finali del giocatore nel formato:
-- Name: {name}
-- Health: {finalHealth}
-- Level: {finalLevel}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Lua online