Trong một công văn --- những gì bạn thấy trong hầu hết các ngôn ngữ OO hiện đại --- một phương pháp là được gửi dựa trên loại thời gian chạy của một đối tượng duy nhất. Điều này hiển thị dưới dạng toán tử dấu chấm (trong ruby, java, javascript, v.v.) hoặc toán tử mũi tên (perl, C++).
# look, ma single dispatch!
# method on obj's run-time type that is called
dentist.work_on(patient)
văn đôi, sau đó, sẽ dựa vào loại thời gian chạy của hai đối tượng. Có một vài cách mà điều này có thể xem xét; và phương pháp nào nên sống?
# 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
Các ngôn ngữ như ngôn ngữ có nhiều công văn tổng quát ví dụ thứ hai ở trên; họ xem xét các loại thời gian chạy là tất cả thông số khi chọn phương thức nào để chạy. Xem ví dụ this blog post về groovy và nhiều công văn.
Hầu hết các ngôn ngữ OO hiện đại chỉ có một công văn và nhiều công văn mẫu là một nỗ lực để nhận được lợi ích của nhiều công văn sang ngôn ngữ. Nó thậm chí hoạt động cho các ngôn ngữ động như ruby. Nó hoạt động bằng cách thực hiện một công văn hai lần liên tiếp. Cuộc gọi phương thức đầu tiên sẽ gọi một phương thức trên đối tượng thứ hai.
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
Công văn đôi mẫu là cái mà tôi gọi một mô hình cấp thấp vì mô hình khác được xây dựng trên đó. Ví dụ: mẫu Khách truy cập dựa nhiều vào mẫu công văn kép.
Cập nhật Chỉ cần thấy GIST của bạn. Gist đầu tiên của bạn không thực sự làm công văn kép. Chắc chắn, bạn đang gửi đi hai lần, nhưng bạn không thay đổi hành vi trong lần gửi thứ hai đó. Để thay đổi nó thành công văn kép, tôi sẽ làm một cái gì đó như thế này.
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)
Bạn có thể có may mắn hơn trên http: // http: //programmers.stackexchange.com/. Trong khi đây là một câu hỏi thú vị, nó không thực sự phù hợp cho Stack Overflow; trang web này có xu hướng thích các câu hỏi cụ thể hơn với "câu trả lời đúng". –
Tôi không đồng ý; đây là một câu hỏi hay để hỏi tại SO –