Menu
Coddy logo textTech

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 fonctionnalité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 ne doivent pas appartenir au 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

Appliquez les deux mixins à votre classe en utilisant 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 à 5, 3

Une précaution : si deux mixins définissent le même nom de méthode, le second appliqué remplacera le premier. Gardez les méthodes de vos mixins distinctes afin d’éviter tout comportement inattendu.

challenge icon

Défi

Facile

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

Vous organiserez votre code sur quatre fichiers :

  • Attacker.lua : Créez 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éez un mixin avec une méthode :heal(amount) qui ajoute la valeur à self.health et affiche {self.name} heals for {amount}. Health: {newHealth}
  • Character.lua : Créez une classe Character avec un constructeur :new(name, health, damage) qui stocke les trois attributs. Appliquez les mixins Attacker et Healer afin que chaque personnage puisse attaquer et se soigner. Incluez une méthode :status() qui affiche {name} - Health: {health}, Damage: {damage}
  • main.lua : Écrivez ici la fonction utilitaire applyMixin. Lisez les entrées correspondant au nom, à la santé et aux dégâts d'un personnage, à une cible à attaquer et à une quantité de soins. Créez un Character, affichez son statut, faites-lui attaquer la cible, se soigner, puis affichez à nouveau son statut.

Vous recevrez 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)

Votre sortie doit montrer le personnage utilisant les deux capacités des 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 devrait ê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. C'est toute la puissance de la combinaison de plusieurs mixins !

Essayez vous-même

-- Fichier principal

-- TODO: Écrire la fonction d'aide 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 disponible 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 name, health et damage donnés

-- TODO: Afficher le statut du character

-- TODO: Faire en sorte que le character attaque la cible

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

-- TODO: Afficher à nouveau le statut du character
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