Visitor pattern. Java

Question:

I implement it for the first time, and something didn't work.

public interface FieldVisitor {
    Object visit(Field field);
}

And these are the methods from the implementation:

private FieldVisitor factory = new FieldVisitor() {
    public Object visit(PresetField presetField) {
        ....
    }

    public Object visit(StringField stringField) {
        ....
    }

    @Override
    public Object visit(Field field) {
        System.out.println(field.getClass());
        ....
    }
};

I call it like this:

public Node getFieldFor(Field field) {
    return (Node) factory.visit(field);
}

It can be seen that objects of different classes are coming:

class com.dma.params.model.field.PresetField
class com.dma.params.model.field.PresetField
class com.dma.params.model.field.NumberField
class com.dma.params.model.field.NumberField
class com.dma.params.model.field.StringField
class com.dma.params.model.field.BooleanField

However, as you can see, I only get into the method for the superclass. In general, as I understood what type of pointer, such a function is called. How can I change this behavior? So that the function is called for the actual type, or am I stupid somewhere with the pattern?

Answer:

Because it’s not like that at all.

First, the visitor interface must declare methods for all classes in the hierarchy.

public interface FieldVisitor {
    Object visit(PresetField field);
    Object visit(StringField field);
    ...
}

Secondly, the ancestor of the hierarchy declares an abstract accept method, in which a visitor is accepted

class Field {
    ...
    public abstract void accept(FieldVisitor visitor);
    ...
}

Thirdly, specific such descendants implement / override the acceptor method in such a way that the visitor method is called for the required (own) class

class StringField {
    ...
    @Override
    public abstract void accept(FieldVisitor visitor) {
        visitor.visit(this); // вызов visit(StringField field)
    }
    ...
}

Finally, the visitor can visit the hierarchy, having previously implemented the visitor's interface by calling the acceptor

...
field.accept(new FieldVisitor() {
    @Override
    Object visit(PresetField field) {
        ...
    }

    @Override
    Object visit(StringField field) {
        ...
    }

});
...

Thanks to polymorphism, the accept of a particular class is called, which in turn calls its "own" overloaded visitor method.

Scroll to Top