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 se passe-t-il si vous voulez partager un comportement entre des classes non liées ?

Un Player et un MenuItem pourraient 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 « mixez » ces fonctions dans une classe en les 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 possède :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 sur la classe :

local p = setmetatable({}, Player)
p:log("Player created")  -- [LOG] Joueur 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 la journalisation, la sérialisation ou les méthodes de description — entre des classes qui n'ont par ailleurs rien en commun.

challenge icon

Défi

Facile

Construisons un système de marquage (tagging) en utilisant des 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 de tags — utile pour catégoriser des articles, des publications ou toute entité nécessitant des étiquettes.

Vous organiserez votre code sur trois fichiers :

  • Taggable.lua : Créez une table mixin contenant deux méthodes :
    • :addTag(tag) — ajoute un tag à self.tags (suppose que la table existe)
    • :listTags() — affiche tous les tags 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 stocke le titre et initialise une table tags vide. Appliquez le mixin Taggable pour donner aux instances d'Article des capacités de marquage. Incluez une méthode :getTitle() qui retourne le titre de l'article.
  • main.lua : Écrivez la fonction utilitaire applyMixin ici (vous l'utiliserez dans Article.lua via require). Ensuite, lisez les entrées pour un titre d'article et deux tags. Créez un Article, ajoutez-lui les deux tags, affichez le titre et listez tous les tags.

Vous recevrez trois entrées :

  1. Le titre de l'article (une chaîne de caractères)
  2. Le premier tag à ajouter (une chaîne de caractères)
  3. Le deuxième tag à ajouter (une chaîne de caractères)

Votre sortie doit afficher le titre de l'article suivi de ses tags :

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

Rappel : les méthodes du mixin fonctionnent parce que les instances d'Article possèdent une table tags sur laquelle les méthodes du mixin peuvent opérer. Le mixin ne crée pas cette table — c'est votre constructeur Article qui le fait. Le mixin fournit simplement le comportement partagé !

Essayez vous-même

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

-- TODO: Implémenter la fonction applyMixin
-- Cette fonction devrait 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 étiquettes (tags) à l'article

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

-- TODO: Lister toutes les étiquettes 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