gpt4 book ai didi

ruby - 尝试理解双重调度模式

转载 作者:数据小太阳 更新时间:2023-10-29 06:45:57 24 4
gpt4 key购买 nike

我一直在努力理解 double-dispatch pattern并且很难过。我终于尝试了一个示例程序来帮助自己理解。 Here's要旨。但后来我决定尝试一下 without Double dispatch解决方案看起来并没有比平时更糟糕。我做错了什么?

编辑:根据建议,我发布了这个问题 here .保留此链接以进行重定向。

最佳答案

在单一分派(dispatch)中——您在大多数现代 OO 语言中看到的——方法是根据单个对象的运行时类型分派(dispatch)的。这显示为点运算符(在 ruby​​、java、javascript 等中)或箭头运算符(perl、c++)。

# look, ma single dispatch!
# method on obj's run-time type that is called
dentist.work_on(patient)

那么,双重分派(dispatch)将基于两个 对象的运行时类型。这看起来有几种方式;该方法应该在哪个对象上运行?

# 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 这样具有多重分派(dispatch)的语言概括了上面的第二个例子;在选择要运行的方法时,他们会考虑所有 参数的运行时类型。参见示例 this blog post关于 groovy 和多重分派(dispatch)。

大多数现代 OO 语言只有单次分派(dispatch),而多分派(dispatch)模式 是一种将多分派(dispatch)的好处融入语言的尝试。它甚至适用于像 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

双重分派(dispatch)模式 是我所说的低级模式,因为其他模式都是建立在它之上的。例如,访问者模式在很大程度上依赖于双重分派(dispatch)模式。


更新 刚看到您的要点。你的第一个要点并不是真正的双重调度。当然,您要分派(dispatch)两次,但您并没有改变第二次分派(dispatch)中的行为。要将其更改为双重分派(dispatch),我会做这样的事情。

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)

关于ruby - 尝试理解双重调度模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15845748/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com