可以使用访问者模式执行通用双重调度吗? [英] Can the Visitor Pattern to be used to perform generic double dispatch?

查看:123
本文介绍了可以使用访问者模式执行通用双重调度吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您搜索Visitor Pattern的通用版本,您会发现如下所示:

  public abstract class Element {
public void accept(Visitor< ;? extends Element> v){
v.visit(this);
}
}

public interface Visitor< T extends Element> {
无效访问(T元素);

(改编自泛型和访问者模式)。

然而,这似乎禁止双重调度,因为第二个调度 - 依赖于方法重载的调度 - 对于泛型方法参数是不可能的。那么,使用泛型与访客模式禁止双派遣?

解决方案

它不会破坏它,只会让它变丑。而不是:

  class MyVisitor实现Visitor< Element> {

void visit(ElementA ea) {..}

void visit(ElementB eB){..}

}

您最终不得不使用 instanceof 添加调度:

<$ p (元素A的实例){$ b $ {










//发送到方法
visit((ElementA)e);

else(e instanceof ElementB){
//或者在这里执行逻辑..
}

}

void visit(ElementA ea){..}

}

Edit
您可以有这样的解决方案:

  class ElementVisitor {

void visit(ElementA ea)

void visit(ElementB eb)

如果客户端现在喜欢:

  class ElementA {

void accept(ElementVisitor ev){
ev.accept(this); //这次调用将被调度访问(元素A)
}

}



然后访问被调度到正确的方法。这种方法的问题在于它不是通用的,您必须为每个要访问的类型族编写一个不同的访问者界面。另一种方法是只有一个访问者所有类型的接口。


If you search for generic versions of Visitor Pattern, you find things like this:

public abstract class Element {
    public void accept(Visitor<? extends Element> v) {
        v.visit(this);
    }
}

public interface Visitor<T extends Element> {
    void visit(T element);
}

(adapted from Generics and the visitor pattern).

However, this seems prohibit double dispatch, since the "second" dispatch—the one that depends on method overloading—is not possible with the generic method parameter. So, does using generics with the Visitor Pattern prohibit double dispatch?

解决方案

It doesn't destroy it, just makes it ugly. Instead of having:

 class MyVisitor implement Visitor<Element>{

   void visit(ElementA ea) {..}

   void visit(ElementB eB) {..}

} 

you end up having to add the dispatching yourself with instanceof :

class MyVisitor implement Visitor<Element>{

   void visit(Element e) { 

       if(e instanceof ElementA) {

             //dispatch to the method
             visit((ElementA) e); 

       else( e instanceof ElementB) {
            //or do the logic right here ..
      }

   }

   void visit(ElementA ea) {..}

} 

Edit You can have such a solution:

class ElementVisitor {

 void visit(ElementA ea)

 void visit(ElementB eb)

}

If now the client does like:

 class ElementA {

   void accept(ElementVisitor ev) { 
       ev.accept(this); // this call will be dispatched to visit(ElementA)
  }

}

then the visit is dispatched to the right method. The problem with this approach is that its not generic, you have to write a different Visitor interface for each family of types to be visited. The other way you just have one Visitor interface for all types.

这篇关于可以使用访问者模式执行通用双重调度吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆