Menu
Coddy logo textTech

Logique de validation

Fait partie de la section Object Oriented Programming du Journey Lua de Coddy — leçon 47 sur 70.

Jusqu'à présent, nous avons exploré différentes manières de protéger les données : les conventions de nommage signalent l'intention, les fermetures (closures) masquent complètement les variables, et les tables en lecture seule empêchent toute modification. Mais souvent, vous avez besoin d'un juste milieu : permettre des modifications, mais seulement celles qui sont valides.

C'est là que les méthodes de type « setter » deviennent puissantes. Au lieu de simplement assigner une valeur, un setter peut vérifier si la nouvelle valeur est cohérente avant de l'accepter :

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

Lorsque quelqu'un appelle person:setAge(-5), la méthode intercepte l'entrée non valide et refuse la mise à jour. L'état de l'objet reste cohérent. Sans cette protection, des données erronées pourraient corrompre silencieusement votre programme — imaginez le calcul des prestations de retraite avec un âge négatif.

La validation peut être aussi simple ou complexe que nécessaire. Vous pourriez vérifier des plages de valeurs, vérifier des types ou vous assurer que les valeurs correspondent aux formats attendus. Le principe clé est que le setter agit comme un garde-barrière, garantissant que seules des données cohérentes entrent dans votre objet.

challenge icon

Défi

Facile

Construisons une classe Player qui protège ses attributs de santé et de niveau en utilisant une logique de validation dans les méthodes setter ! Cela garantit que les personnages du jeu ne se retrouvent jamais avec des statistiques impossibles.

Vous organiserez votre code sur deux fichiers :

  • Player.lua : Créez une classe qui gère les statistiques d'un joueur avec une validation appropriée. Le constructeur :new(name) doit initialiser le joueur avec un nom, _health défini sur 100, et _level défini sur 1. Incluez ces méthodes :
    • :getName() — retourne le nom du joueur
    • :getHealth() — retourne la santé actuelle
    • :getLevel() — retourne le niveau actuel
    • :setHealth(value) — met à jour la santé uniquement si la valeur est comprise entre 0 et 100 (inclus). Si elle est invalide, affichez Error: Health must be between 0 and 100 et ne modifiez pas la valeur.
    • :setLevel(value) — met à jour le niveau uniquement si la valeur est égale ou supérieure à 1. Si elle est invalide, affichez Error: Level must be at least 1 et ne modifiez pas la valeur.
  • main.lua : Importez votre module Player et lisez un nom de joueur, puis deux valeurs pour tester les setters. Créez un joueur, tentez de définir sa santé sur la première valeur, tentez de définir son niveau sur la seconde valeur, puis affichez les statistiques finales du joueur.

Vous recevrez trois entrées :

  1. Le nom du joueur
  2. Une valeur de santé à tenter de définir (un nombre, qui pourrait être valide ou invalide)
  3. Une valeur de niveau à tenter de définir (un nombre, qui pourrait être valide ou invalide)

Votre sortie doit afficher tous les messages d'erreur provenant de tentatives invalides, suivis des statistiques finales du joueur :

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

Par exemple, si les entrées sont Hero, -20, et 5, la sortie devrait être :

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

Le setter de santé a rejeté -20 (maintenant la santé à 100), tandis que le setter de niveau a accepté 5 comme valide.

Si les entrées sont Warrior, 75, et 0, la sortie devrait être :

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

Aide-mémoire

Les méthodes setter vous permettent de valider les données avant de mettre à jour les propriétés de l'objet, garantissant que seules les valeurs valides sont acceptées.

Un setter de base avec validation :

function Person:setAge(newAge)
    if newAge < 0 then
        print("Error: Age cannot be negative")
        return
    end
    self._age = newAge
end

Le setter agit comme un garde-barrière — il vérifie si la nouvelle valeur est valide avant de mettre à jour la propriété interne. Si la validation échoue, il affiche une erreur et s'arrête prématurément sans modifier les données.

La validation peut inclure :

  • Des vérifications de plage (par ex., age >= 0)
  • Des limites de bornes (par ex., 0 <= health <= 100)
  • La vérification de type
  • La validation de format

Cela empêche les données invalides de corrompre l'état de votre objet et maintient la cohérence de votre programme.

Essayez vous-même

-- Charger le module Player
local Player = require('Player')

-- Lire les entrées
local name = io.read()
local healthValue = tonumber(io.read())
local levelValue = tonumber(io.read())

-- TODO : Créer un nouveau joueur avec le nom donné

-- TODO : Tenter de définir la santé du joueur à healthValue

-- TODO : Tenter de définir le niveau du joueur à levelValue

-- TODO : Afficher les statistiques finales du joueur au format :
-- Nom : {name}
-- Santé : {finalHealth}
-- Niveau : {finalLevel}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Object Oriented Programming