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")
endApplique 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, 3Une 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.
Défi
FacileConstruisons 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 champsnameetdamage)Healer.lua: crée un mixin avec une méthode:heal(amount)qui ajoute la quantité àself.healthet 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 auxiliaireapplyMixin. 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 :
- Nom du personnage (une chaîne de caractères)
- Santé initiale (un nombre)
- Valeur des dégâts (un nombre)
- Nom de la cible à attaquer (une chaîne de caractères)
- 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: 25Chaque 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
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
1Le concept de « self »
Tables avec fonctions« self » expliciteLa syntaxe avec deux-pointsPoint vs deux-pointsRécapitulatif - Point mobile4Projet : Banque numérique
Configuration du projetMéthode de dépôt7Polymorphisme et Redéfinition
Redéfinition de méthodesAppeler des méthodes parentesDuck TypingInterface communeVérification du typeRécapitulatif - Rôles des employés10Projet : Gestionnaire de formes
Configuration du projetClasse RectangleClasse CercleMéthode PérimètreCollection de formesAire totaleFiltrer les formes2Modèle de prototype de classe
Le concept de prototypeLiaison avec __indexLe constructeur :new()Initialisation des attributsInstances indépendantesRécapitulatif - Usine de voitures5Surcharge d'opérateurs en POO
Additionner des objetsSoustraire des objetsConcaténer des objetsComparer des objets (<, >)Récapitulatif - Calculs de portefeuille8Encapsulation
Conventions de nommageClosures pour la confidentialitéAccès via les ClosuresTables en lecture seuleLogique de validationRécapitulatif - Coffre-fort sécurisé11Patrons de conception (Lite)
Fonctions FactoryTable SingletonPatron IteratorObserver (Écouteur)Récapitulatif - Logger Factory3État et comportement des objets
Variables d'instanceMéthodes GetterMéthodes SetterPropriétés calculéesFormatage de chaînesVérifications d'égalitéRécapitulatif - Note de l'étudiant6Bases de l'héritage
Mise en place de l'héritageHériter des méthodesÉtendre le constructeurAjouter des méthodes enfantsPartagé vs UniqueRécapitulatif - Hiérarchie des formes9Composition et Mixins
Relation 'A un'DélégationMixins simplesAppliquer plusieurs MixinsMixins vs HéritageRécapitulatif - Assemblage de robotsEntraînez-vous par vous-même : Compilateur Lua en ligne