Menu
Coddy logo textTech

Mixins simples

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

La composition vous permet de placer des objets à l’intérieur d’autres objets. Mais que faire si vous voulez partager un comportement entre des classes sans lien ?

Un Player et un MenuItem peuvent tous deux avoir besoin d’une méthode :describe(), mais ils ne partagent pas de classe parente. C’est là que les mixins interviennent.

Un mixin est simplement une table contenant des fonctions. Vous « mélangez » ces fonctions à une classe en les y copiant :

local Printable = {}

function Printable:describe()
    print("Object: " .. tostring(self))
end

function Printable:log(message)
    print("[LOG] " .. message)
end

Pour appliquer ce mixin à une classe, vous copiez chaque fonction de la table du mixin dans la table de la classe :

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

local Player = {}
Player.__index = Player

applyMixin(Player, Printable)  -- Maintenant Player a :describe() et :log()

Après avoir appliqué le mixin, toute instance de Player peut appeler ces méthodes comme si elles étaient définies directement dans la classe :

local p = setmetatable({}, Player)
p:log("Player created")  -- [LOG] Player créé

Contrairement à l’héritage, les mixins ne créent pas de relation parent-enfant. Vous copiez simplement des fonctions d’une table à une autre.

Cela rend les mixins parfaits pour partager des comportements utilitaires, comme les méthodes de journalisation, de sérialisation ou de description, entre des classes qui n’ont par ailleurs rien en commun.

challenge icon

Défi

Facile

Construisons un système d’étiquettes à l’aide de mixins ! Vous allez créer un mixin Taggable qui peut être appliqué à n’importe quelle classe, donnant aux objets la capacité de gérer une collection d’étiquettes, utile pour catégoriser des éléments, des articles ou toute entité nécessitant des étiquettes.

Vous allez organiser votre code dans trois fichiers :

  • Taggable.lua : créez une table de mixin contenant deux méthodes :
    • :addTag(tag) : ajoute une étiquette à self.tags (en supposant que la table existe)
    • :listTags() : affiche toutes les étiquettes au format Tags: tag1, tag2, tag3 (ou Tags: none si elle est vide)
  • Article.lua : créez une classe Article avec un constructeur :new(title) qui enregistre le titre et initialise une table tags vide. Appliquez le mixin Taggable pour donner aux instances de Article des fonctionnalités de gestion des étiquettes. Ajoutez une méthode :getTitle() qui renvoie le titre de l’article.
  • main.lua : écrivez ici la fonction utilitaire applyMixin (vous l’utiliserez dans Article.lua via require). Lisez ensuite les entrées correspondant au titre d’un article et à deux étiquettes. Créez un Article, ajoutez-lui les deux étiquettes, affichez le titre, puis affichez toutes les étiquettes.

Vous recevrez trois entrées :

  1. Le titre de l’article (une chaîne de caractères)
  2. La première étiquette à ajouter (une chaîne de caractères)
  3. La deuxième étiquette à ajouter (une chaîne de caractères)

Votre sortie doit afficher le titre de l’article suivi de ses étiquettes :

Title: {title}
Tags: {tag1}, {tag2}

Par exemple, si les entrées sont Lua Basics, programming et tutorial, la sortie doit être :

Title: Lua Basics
Tags: programming, tutorial

N’oubliez pas : les méthodes du mixin fonctionnent parce que les instances de Article possèdent une table tags sur laquelle les méthodes du mixin peuvent agir. Le mixin ne crée pas cette table. C’est votre constructeur Article qui la crée. Le mixin fournit simplement le comportement partagé !

Essayez vous-même

-- Fichier principal pour le système de tags
local Taggable = require('Taggable')
local Article = require('Article')

-- TODO: Implémenter la fonction applyMixin
-- Cette fonction doit copier toutes les méthodes d'une table mixin vers une table cible
function applyMixin(target, mixin)
    -- TODO: Parcourir le mixin et copier chaque méthode vers target
end

-- Lire les entrées
local title = io.read()
local tag1 = io.read()
local tag2 = io.read()

-- TODO: Créer un Article avec le titre donné

-- TODO: Ajouter les deux tags à l'article

-- TODO: Afficher le titre au format : Title: {title}

-- TODO: Lister tous les tags en utilisant la méthode listTags
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