문제

I am starting to work with Java after some projects in C# and C++.

I wanted to design visitor interfaces like this:

public interface ActionVisitor<A> {
    void visitAction(A action);    
}

public interface MySmallActionVisitor 
extends ActionVisitor<ActionA>,
    ActionVisitor<ActionB>
{

}

public interface MyFullActionVisitor 
extends ActionVisitor<ActionA>,
    ActionVisitor<ActionB>,ActionVisitor<ActionC>,ActionVisitor<ActionD> //....
{

}

Of course this doesn't work because of type erasure. (The reason why I want something like this is that I will have different Visitor interfaces for different groups of Actions that can be visited.)

The only solution that comes to my mind is to declare interfaces

public interface ActionAVisitor {
        void visitAction(ActionA action);    
    }
public interface ActionBVisitor {
        void visitAction(ActionB action);    
    }
//...

and then

public interface MySmallActionVisitor 
extends ActionAVisitor, ActionBVisitor
{

}

This would work, but I wouldn't like the declaration of all the ActionXVisitor-Interfaces which is stupid repetition and lots of files...

Do you have any ideas how to do this better?

Thanks a lot!

도움이 되었습니까?

해결책

I work with a large and complex library in Java which extensively uses the Visitor Pattern in a very clean and neat way. In particular, I came across with the same problem of type erasure and it is solved now.

If you have a chance, please have a look at an article I've written about this.

It's a long article, which explains in detail what the Visitor pattern is about conceptually and, in last part of the article, it is discussed a real life example which involves polymorphism and type erasure.

Cheers

다른 팁

I would use a single unparameterized visitor interface, then inside the visitor method do the dispatch based on type.

There's no way to be able to avoid instanceof of inside the method. But you can make it more graceful:

public interface MarkerInterface{}

public interface ActionVisitor<T extends MarkerInterface> {
void visitAction(T action);}

public class A implements MarkerInterface{}

public class B implements MarkerInterface{}

public class MySmallActionVisitor implements ActionVisitor<MarkerInterface>{

@Override
public void visitAction(MarkerInterface action) {
    if(action instanceof A){

    }
    else if(action instanceof B){

    }
}

}

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top