Les protocoles sont un mécanisme qui permet d'obtenir du polymorphisme en Elixir quand on veut qu'un comportement varie selon le type de données.
Les protocoles se définissent à l'aide de defprotocol et comportent un ou plusieurs en-têtes de fonction.
defprotocol Reversible do
def reverse(term)
end
Les protocoles s'implémentent à l'aide de defimpl.
defimpl Reversible, for: List do
def reverse(term) do
Enum.reverse(term)
end
end
Un protocole peut être implémenté pour n'importe quel type de données Elixir existant ou pour une structure.
Lorsqu'une fonction de protocole est appelée, l'implémentation appropriée est automatiquement choisie en fonction du type du premier argument.
Tu développes ton propre jeu vidéo de rôle. Dans ton jeu, il y a des personnages et des objets. L'une des nombreuses actions que tu peux effectuer avec un objet consiste à faire manger cet objet à un personnage.
Tous les objets ne sont pas comestibles, et les objets comestibles n'ont pas tous les mêmes effets sur le personnage. Certains objets, lorsqu'on les mange, se transforment en un autre objet (par exemple, si tu manges une pomme, il te reste le trognon).
Pour permettre toute cette flexibilité, tu as décidé de créer un protocole Edible que certains objets peuvent implémenter.
Crée le protocole RPG.Edible. Le protocole possède une fonction : eat. La fonction eat prend un objet et un personnage, et renvoie un sous-produit et un personnage.
Implémente le protocole RPG.Edible pour l'objet RPG.LoafOfBread. Quand il est mangé, une miche de pain donne au personnage 5 points de vie et n'a pas de sous-produit.
RPG.Edible.eat(%RPG.LoafOfBread{}, %RPG.Character{health: 31})
# => {nil, %RPG.Character{health: 36, mana: 0}}
Implémente le protocole RPG.Edible pour l'objet RPG.ManaPotion. Quand elle est mangée, une potion de mana donne au personnage autant de points de mana que la force de la potion, et produit une bouteille vide.
RPG.Edible.eat(%RPG.ManaPotion{strength: 13}, %RPG.Character{mana: 50})
# => {%RPG.EmptyBottle{}, %RPG.Character{health: 100, mana: 63}}
Implémente le protocole RPG.Edible pour l'objet RPG.Poison. Quand il est mangé, un poison retire tous les points de vie au personnage, et produit une bouteille vide.
RPG.Edible.eat(%RPG.Poison{}, %RPG.Character{health: 3000})
# => {%RPG.EmptyBottle{}, %RPG.Character{health: 0, mana: 0}}
Inscris-toi sur Exercism pour apprendre et maîtriser Elixir avec 58 concepts168 exercices, et un vrai mentorat humain, le tout gratuitement.