Try to understand the double send pattern

I am trying to get a double send pattern and with difficulty. I finally tried an example program to help myself understand. That is the point. But then I decided to try without double sending , and the solution did not look more scary than usual. What am I doing wrong?

Edit: as per the suggestion I posted this question here . Saving this link for redirection.

+8
ruby design-patterns
source share
1 answer

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! # method on obj run-time type that is called dentist.work_on(patient) 

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. # 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 

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) 
+17
source share

All Articles