ruby - Attempt at understanding the double-dispatch pattern -
i've been trying grok double-dispatch pattern , having hard time. attempted sample program myself understand. here's gist. decided attempt without double dispatch , solution didn't more terrible usual. doing wrong?
edit: per suggestion, i've posted question here. keeping link around redirects.
in single dispatch---what see in modern oo languages---a method dispatched based on run-time type of single object. shows dot operator (in ruby, java, javascript, etc.) or arrow operator (perl, c++).
# look, ma single dispatch! # method on obj's run-time type called dentist.work_on(patient) double dispatch, then, based on run-time type of two objects. there few ways look; , on object should method live?
# hmm, looks weird. # method in dentist.class or patient.class? (dentist, patient).do_dentistry() # okay, looks more familiar; method lives on obj1.class # works in static-typed languages support double dispatch # in declare type of method parameters. dentist.work_on(patient) class dentist def work_on(adult patient); ...; end def work_on(child patient); ...; end end languages groovy have multiple dispatch generalize second example above; consider run-time types of all parameters when choosing method run. see example this blog post groovy , multiple dispatch.
most modern oo languages have single dispatch , multiple dispatch pattern attempt benefits of multiple dispatch language. works dynamic languages ruby. works doing single dispatch twice in row. first method call call method on 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 the double dispatch pattern call low-level pattern because other patterns built on it. example, visitor pattern relies heavily on double dispatch pattern.
update saw gists. first gist isn't doing double dispatch. sure, you're dispatching twice, you're not changing behavior in second dispatch. change double dispatch i'd 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's pie" end end sandwich.new.make(chicken.new) stew.new.make(chicken.new) casserole.new.make(beef.new)
Comments
Post a Comment