In a separate dispatch --- what you see in most modern OO languages ββ- the method is dispatched based on the runtime type of a single object. This is displayed as a dot operator (in ruby, java, javascript, etc.) Or an arrow operator (perl, C ++).
# look, ma single dispatch!
Then the double dispatch will be based on the runtime type of the two objects. There are several ways this might look; and on what object should this method live?
# Hmm, this looks weird.
Languages ββlike groovy, which have multiple dispatch, summarize the second example above; they consider the runtime types of all parameters when choosing a method to run. See for example this blog post about groovy and multiple posting.
Most modern OO languages ββhave only one send, and the multi-send pattern is an attempt to take advantage of the multiple send to the language. It even works for dynamic languages ββlike ruby. It works by doing separate dispatch twice in a row. The first method call will call the method for the second object.
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
A dual submit template is what I call a low-level template because other templates are built on it. For example, the visitor pattern is heavily dependent on the double-submit pattern.
Update Just saw your gists. Your first meaning is not to do double dispatch. Of course, you send twice, but you do not change the behavior in the second send. To change it to double sending, I would do something like this.
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 Pie" end end Sandwich.new.make(Chicken.new) Stew.new.make(Chicken.new) Casserole.new.make(Beef.new)
Michael Deardeuff
source share