设计模式 – 访客模式与双调度之间的差异

我正在阅读关于访问者模式,它看起来像双调度。两者之间有什么区别。
这两个术语意思相同。

参考: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)

调用将重定向到与pa和pb的实际运行时类型匹配的覆盖。 (您可以将此推广到任何数量的参数)

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

换句话说,伪代码

void fn(virtual base_a*, base_b*) 

成为(实C)

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

注意,这里没有更多的虚拟在base_b之前,从现在是静态的。
一个电话像

如果pa指向derived_a2并且pb指向derived_b1将被分派到p1→pn(pb)
derived_a2 :: fn(base_b *),不管是否有一个derived_a2 :: fn(derived_b1 *):pb指向的对象的运行时类型不考虑。

访问者模式的想法是调用一个对象的虚拟分派,该对象调用(最终返回)另一个的虚拟分派:

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 *)。

http://stackoverflow.com/questions/9818132/difference-betwen-visitor-pattern-double-dispatch

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:设计模式 – 访客模式与双调度之间的差异