Dmitry Minkovsky
Dmitry Minkovsky

Reputation: 38173

Can the Visitor Pattern to be used to perform generic double dispatch?

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?

Upvotes: 0

Views: 767

Answers (1)

Chirlo
Chirlo

Reputation: 6132

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.

Upvotes: 2

Related Questions