Menu
CoddyTech

Appliquer plusieurs Mixins

Fait partie de la section Programmation orientée objet du Journey Lua de Coddy. Leçon 52 sur 70.

Un seul mixin ajoute un ensemble de comportements à une classe. Mais les objets réels ont souvent besoin de capacités provenant de plusieurs sources. Un objet de jeu peut avoir besoin de se déplacer et d’être visible à l’écran : deux préoccupations distinctes qui n’ont pas leur place dans le même mixin.

La solution est simple : appliquez plusieurs mixins à la même classe. Chaque mixin apporte ses propres méthodes, et la classe se retrouve avec toutes ces méthodes :

local Movable = {}
function Movable:move(dx, dy)
    self.x = self.x + dx
    self.y = self.y + dy
end

local Visible = {}
function Visible:show()
    print("Showing at " .. self.x .. ", " .. self.y)
end
function Visible:hide()
    print("Hidden")
end

Applique les deux mixins à ta classe à l’aide de la même fonction utilitaire que précédemment :

local function applyMixin(class, mixin)
    for key, value in pairs(mixin) do
        class[key] = value
    end
end

local GameObject = {}
GameObject.__index = GameObject

applyMixin(GameObject, Movable)
applyMixin(GameObject, Visible)

Maintenant, les instances de GameObject peuvent à la fois se déplacer et s’afficher :

local obj = setmetatable({x = 0, y = 0}, GameObject)
obj:move(5, 3)
obj:show()  -- Affichage en 5, 3

Une mise en garde : si deux mixins définissent le même nom de méthode, le deuxième appliqué écrasera le premier. Garde des méthodes distinctes dans tes mixins pour éviter les comportements inattendus.

challenge icon

Défi

Facile

Construisons une classe Character pour un jeu qui combine plusieurs capacités à l’aide de mixins ! Ton personnage pourra à la fois attaquer des ennemis et se soigner : deux comportements distincts provenant de mixins séparés.

Tu organiseras ton code dans quatre fichiers :

  • Attacker.lua : crée un mixin avec une méthode :attack(targetName) qui affiche {self.name} attacks {targetName} for {self.damage} damage! (suppose que l’objet possède les champs name et damage)
  • Healer.lua : crée un mixin avec une méthode :heal(amount) qui ajoute la quantité à self.health et affiche {self.name} heals for {amount}. Health: {newHealth}
  • Character.lua : crée une classe Character avec un constructeur :new(name, health, damage) qui stocke les trois attributs. Applique les mixins Attacker et Healer afin que chaque personnage puisse attaquer et se soigner. Ajoute une méthode :status() qui affiche {name} - Health: {health}, Damage: {damage}
  • main.lua : écris ici la fonction auxiliaire applyMixin. Lis les entrées correspondant au nom du personnage, à sa santé, à ses dégâts, à une cible à attaquer et à une quantité de soins. Crée un Character, affiche son état, fais-le attaquer la cible, soigne-le, puis affiche à nouveau son état.

Tu recevras cinq entrées :

  1. Nom du personnage (une chaîne de caractères)
  2. Santé initiale (un nombre)
  3. Valeur des dégâts (un nombre)
  4. Nom de la cible à attaquer (une chaîne de caractères)
  5. Quantité de soins (un nombre)

Ta sortie doit montrer le personnage utilisant les capacités des deux mixins :

{name} - Health: {health}, Damage: {damage}
{name} attacks {target} for {damage} damage!
{name} heals for {healAmount}. Health: {newHealth}
{name} - Health: {newHealth}, Damage: {damage}

Par exemple, si les entrées sont Warrior, 100, 25, Goblin et 30, la sortie doit être :

Warrior - Health: 100, Damage: 25
Warrior attacks Goblin for 25 damage!
Warrior heals for 30. Health: 130
Warrior - Health: 130, Damage: 25

Chaque mixin apporte sa propre méthode à la classe Character. Le personnage n’hérite d’aucun des deux mixins. Il acquiert simplement leurs capacités grâce à la fonction applyMixin. Voilà tout l’intérêt de combiner plusieurs mixins !

Essayez vous-même

-- Fichier principal

-- TODO: Écrire la fonction utilitaire applyMixin
-- Cette fonction doit copier toutes les méthodes d’une table mixin vers une table cible
local function applyMixin(target, mixin)
    -- TODO: Implémenter l’application du mixin
end

-- Rendre applyMixin accessible globalement pour que Character.lua puisse l’utiliser
_G.applyMixin = applyMixin

local Character = require('Character')

-- Lire les entrées
local name = io.read()
local health = tonumber(io.read())
local damage = tonumber(io.read())
local targetName = io.read()
local healAmount = tonumber(io.read())

-- TODO: Créer un Character avec le nom, la santé et les dégâts indiqués

-- TODO: Afficher l’état du personnage

-- TODO: Faire attaquer la cible par le personnage

-- TODO: Faire en sorte que le personnage se soigne

-- TODO: Afficher à nouveau l’état du personnage
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 Programmation orientée objet

Entraînez-vous par vous-même : Compilateur Lua en ligne