Мультиметод — Вікіпедія
Мультиме́тод (англ. multimethod) або множи́нна диспетчериза́ція (англ. multiple dispatch) — механізм, який дозволяє вибрати одну з декількох функцій в залежності від динамічних типів або значень аргументів. Є розширенням одиночної диспетчеризації (віртуальних функцій), де вибір методу здійснюється динамічно на основі фактичного типу об'єкта. Множинна диспетчеризація узагальнює динамічну диспетчеризацію для випадків з двома або більшою кількістю об'єктів.
В явному вигляді мультиметоди підтримуються «об'єктною системою типів Common Lisp’а» (CLOS).
Для кращого розуміння різниці між мультиметодами і одиночною диспетчеризацією можна продемонструвати наступний приклад. Уявимо собі гру, в якій поряд з різноманітними іншими об'єктами, присутні астероїди та космічні кораблі. Коли два яких-небудь об'єкти зіштовхуються, програма повинна вибрати певний алгоритм дій, в залежності від того що із чим зіштовхнулось.
В мові з підтримкою мультиметодів, такій, як Common Lisp, код виглядав би так:
(defgeneric collide (x y)) (defmethod collide ((x asteroid) (y asteroid)) ;;астероїд зіштовхується з астероїдом ) (defmethod collide ((x asteroid) (y spaceship)) ;;астероїд зіштовхується з космічним кораблем ) (defmethod collide ((x spaceship) (y asteroid)) ;;космічний корабель зіштовхується з астероїдом ) (defmethod collide ((x spaceship) (y spaceship)) ;;космічний корабель зіштовхується з космічним кораблем )
namespace MultipleDispatch { enum Outcome { Win, Lose, Draw, } abstract class Item { public abstract Outcome Compete(Item item); public abstract Outcome Evaluate(Paper paper); public abstract Outcome Evaluate(Scissors scissors); public abstract Outcome Evaluate(Rock rock); } class Paper : Item { public override Outcome Compete(Item item) => item.Evaluate(this); public override Outcome Evaluate(Paper paper) => Outcome.Draw; public override Outcome Evaluate(Scissors scissors) => Outcome.Win; public override Outcome Evaluate(Rock rock) => Outcome.Lose; } class Scissors : Item { public override Outcome Compete(Item item) => item.Evaluate(this); public override Outcome Evaluate(Paper paper) => Outcome.Lose; public override Outcome Evaluate(Scissors scissors) => Outcome.Draw; public override Outcome Evaluate(Rock rock) => Outcome.Win; } class Rock : Item { public override Outcome Compete(Item item) => item.Evaluate(this); public override Outcome Evaluate(Paper paper) => Outcome.Win; public override Outcome Evaluate(Scissors scissors) => Outcome.Lose; public override Outcome Evaluate(Rock rock) => Outcome.Draw; } class Program { static Item GetRandomItem() { switch (new System.Random().Next(3)) { case 0: return new Paper(); case 1: return new Scissors(); case 2: return new Rock(); default: throw new System.InvalidOperationException("Wrong item type"); } } static void Main(string[] args) { Item item1 = GetRandomItem(); Item item2 = GetRandomItem(); System.Console.WriteLine($"{item1.GetType().Name} - {item1.Compete(item2)} - {item2.GetType().Name}"); } } }
namespace MultipleDispatchPattern { enum Outcome { Win, Lose, Draw, } abstract class Item { public Outcome Compete(Item item) => Evaluate(this as dynamic, item as dynamic); private static Outcome Evaluate(Paper paper1, Paper paper2) => Outcome.Draw; private static Outcome Evaluate(Paper paper, Scissors scissors) => Outcome.Lose; private static Outcome Evaluate(Paper paper, Rock rock) => Outcome.Win; private static Outcome Evaluate(Scissors scissors, Paper paper) => Outcome.Win; private static Outcome Evaluate(Scissors scissors1, Scissors scissors2) => Outcome.Draw; private static Outcome Evaluate(Scissors scissors, Rock rock) => Outcome.Lose; private static Outcome Evaluate(Rock rock, Paper paper) => Outcome.Lose; private static Outcome Evaluate(Rock rock, Scissors scissors) => Outcome.Win; private static Outcome Evaluate(Rock rock1, Rock rock2) => Outcome.Draw; } class Paper : Item { } class Scissors : Item { } class Rock : Item { } class Program { static Item GetRandomItem() { switch (new System.Random().Next(3)) { case 0: return new Paper(); case 1: return new Scissors(); case 2: return new Rock(); default: throw new System.InvalidOperationException("Wrong item type"); } } static void Main(string[] args) { Item item1 = GetRandomItem(); Item item2 = GetRandomItem(); System.Console.WriteLine($"{item1.GetType().Name} - {item1.Compete(item2)} - {item2.GetType().Name}"); } } }
- Bjarne Stroustrup; Yuriy Solodkyy; Peter Pirkelbauer (2007). Open Multi-Methods for C++ (PDF). ACM 6th International Conference on Generative Programming and Component Engineering. Архів оригіналу (PDF) за 29 квітня 2021. Процитовано 2 серпня 2015.
В іншому мовному розділі є повніша стаття Multiple dispatch(англ.). Ви можете допомогти, розширивши поточну статтю за допомогою перекладу з англійської.
|
Це незавершена стаття про мови програмування. Ви можете допомогти проєкту, виправивши або дописавши її. |