访客模式与双重调度的区别

我正在阅读关于访问者模式,并且看起来像Double Dispatch一样。 两者有什么区别吗? 这两个术语是否意味着同样的事情。

参考: http : //www.vincehuston.org/dp/visitor.html

简而言之

他们来自不同的概念,在一些双重派遣不是本地支持的语言中,导致访问者模式作为连接两个(或更多)单个派遣的方式,以便具有多派遣代理。

长久以来

多次调度的想法是 – 基本上 – 允许一个像这样的调用

void fn(virtual base_a*, virtual base_b*); (注意:不是作为类成员:这不是C ++!)

可以被重写为

 void fn(virtual derived_a1*, virtual derived_b1*); void fn(virtual derived_a2*, virtual derived_b1*); void fn(virtual derived_a1*, virtual derived_b2*); void fn(virtual derived_a2*, virtual derived_b2*); 

所以,当打电话

 fn(pa, pb) 

该调用被redirect到与papb的实际运行时types相匹配的覆盖。 (你可以把它推广到任意数量的参数)

在像C ++,C#,Java这样的语言中,这种机制并不存在,运行时types调度基本上只与一个参数一起工作(通过使函数本身成为类的成员,

换句话说,伪码

 void fn(virtual base_a*, base_b*) 

成为(真正的C ++)

 class base_a { public: virtual void fn(base_b*); } 

请注意,这里base_b没有更多的virtual ,从现在开始是静态的。 像一个电话

如果pa指向一个derived_a2,而pb指向一个derived_b1, pa->fn(pb)将被派发到derived_a2 :: fn(base_b *),不pipe在那里是否有一个derived_a2 :: fn(derived_b1 *):run pb指向的对象的时间types不被考虑。

访客模式的想法是,你调用一个对象的虚拟调度,调用(最终返回)另一个对象的虚拟调度:

 class base_a { public: virtual void fn(base_b*)=0; virtual void on_visit(derived_b1*)=0; virtual void on_visit(derived_b2*)=0; }; class base_b { public: virtual void on_call(derived_a1*)=0; virtual void on_call(derived_a2*)=0; }; //forward declarations, to allow pointers free use in other decls. class derived_a1; class derived_b1; class derived_a1: public base_a { public: virtual void fn(base_b* pb) { pb->on_call(this); } virtual void on_visit(derived_b1* p1) { /* useful stuff */ } ... }; class derived_b1: public base_b { public: virtual void on_call(derived_a1* pa1) { pa1->on_visit(this); } ... }; 

现在,像pa->fn(pb)这样的调用,如果pa指向derived_a1,并且pb指向derived_b1,则最终将转到derived_a1::on_visit(derived_b1*)

访客模式是实现双重调度行为的一个解决scheme。 还可以有其他几个解决scheme。 “ 双重派遣 ”一词本身并不能解决问题,事实上,解决scheme是由访问者模式提供的问题。

在C#(4.0)中,可以使用dynamic关键字来实现双重调度,在这种情况下访客模式不是必需的。 这里是我的解决scheme,使用dynamic关键字双重调度问题:

  • C#4.0“dynamic”关键字的优点和缺点?

dynamic调度一般指的是基于运行时信息调度方法的概念 。 大多数OO系统(如Java / C#/ C ++)通常通过virtual方法实现dynamic分派(不pipe所有方法是否依赖于语言)。 这限制了它们根据单个方法参数(隐式对象引用)进行分派。

一般来说,你可能想要根据任意数量的元素进行分派。 例如,Double Dispatch是根据方法的两个参数来调度的要求/能力。

另一方面, 访问者模式通常是多次调度的实现 ,因此在这样的面向对象系统中尤其是双调度(Double Dispatch)。

双重调度是一个技术问题,可以根据语言以不同的方式来解决 – 有些语言直接支持双重调度。 访客模式是一种可以用来解决不同问题的模式。 在C ++的情况下,它是用于双重调度的最常用的(但不是唯一的)解决scheme,但并不是专门用于这种情况,即使在支持双重调度的语言中也是有用的。

维基百科 :

访问者模式在传统的单调度面向对象语言(如Java,Smalltalk和C ++)中模拟双派遣。

另外从维基百科 :

上述问题可以通过模拟双重调度来解决,例如使用访客模式。

Interesting Posts