В одной отправке --- что вы видите на большинстве современных языков OO --- метод отправлен на основе типа времени выполнения одного объекта. Это отображается как оператор точки (в ruby, java, javascript и т. Д.) Или оператор стрелки (perl, C++).
# look, ma single dispatch!
# method on obj's run-time type that is called
dentist.work_on(patient)
двойной отправки, то будет основываться на типе времени выполнения в два объектов. Есть несколько способов, которыми это могло бы выглядеть; и на каком объекте должен жить этот метод?
# Hmm, this looks weird.
# Is the method in to dentist.class or patient.class?
(dentist, patient).do_dentistry()
# okay, this looks more familiar; the method lives on obj1.class
# This only works in static-typed languages which support double dispatch
# in which you declare the type of the method parameters.
dentist.work_on(patient)
class Dentist
def work_on(Adult patient); ...; end
def work_on(Child patient); ...; end
end
Языки, подобные groovy, которые имеют множественную отправку, обобщают второй пример выше; они рассматривают типы времени выполнения всех параметров при выборе способа запуска. См. Например, this blog post о groovy и множественной отправке.
Большинство современных языков OO имеют только одну отправку и множественную отправку Образец - это попытка получить преимущества множественной отправки на язык. Он даже работает для динамических языков, таких как ruby. Он работает, делая одну отправку дважды в строке. Первый вызов метода вызовет метод для второго объекта.
class Dentist
def work_on(patient)
patient.dispatch_work(self)
end
def work_on_adult(patient)
drill_as_hard_as_you_can(patient)
end
def work_on_child(patient)
use_bubble_gum_toothpaste(patient)
give_toothbrush_to(patient)
end
end
class Doctor
def work_on(patient)
patient.dispatch_work(self)
end
def work_on_adult(patient)
do_checkup(patient)
end
def work_on_child(patient)
assure_presence_of(patient.guardian)
ask_questions_to(patient.guardian)
do_checkup(patient)
give_cheap_toy_to(patient)
end
end
class Adult
def dispatch_work(dentist)
dentist.work_on_adult(self)
end
end
class Child
def dispatch_work(dentist)
dentist.work_on_child(self)
end
end
двойной диспетчерская шаблон является то, что я называю шаблон низкого уровня, так как другие модели построены на нем. Например, шаблон посетителя в значительной степени зависит от шаблона двойной отправки.
Update Только видел ваши гов. Ваш первый смысл не делает двойную отправку. Конечно, вы отправляете дважды, но вы не меняете поведение во второй отправке. Чтобы изменить его на двойную отправку, я бы сделал что-то вроде этого.
class Chicken
def make_dispatch dish
dish.make_with_chicken self
end
end
class Beef
def make_dispatch dish
dish.make_with_beef self
end
end
module Dish
def make meat
meat.make_dispatch self
end
end
class Sandwich
include Dish
def make_with_chicken chicken
puts "Grilled Chicken Sandwich"
end
def make_with_beef beef
puts "Roast Beef Sandwich"
end
end
class Stew
include Dish
def make_with_chicken chicken
puts "Thai curry"
end
def make_with_beef beef
puts "Beef stew"
end
end
class Casserole
include Dish
def make_with_chicken chicken
puts "Chicken Pot Pie--or something"
end
def make_with_beef beef
puts "Shepard's Pie"
end
end
Sandwich.new.make(Chicken.new)
Stew.new.make(Chicken.new)
Casserole.new.make(Beef.new)
Возможно, вам удастся на http: // http: //programmers.stackexchange.com/. Хотя это интересный вопрос, это не очень подходит для Stack Overflow; этот сайт, как правило, предпочитает конкретные вопросы с «правильным ответом». –
Я не согласен; это прекрасный вопрос, заданный на SO –