В первый раз реализую, и что-то не заработало.
public interface FieldVisitor {
Object visit(Field field);
}
А это методы из реализации:
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());
....
}
};
Вызываю так:
public Node getFieldFor(Field field) {
return (Node) factory.visit(field);
}
Видно что приходят объекты разных классов:
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
Однако попадаю как видно только в метод для суперкласса. В общем, как я понял, какой тип указателя, такая функция вызывается. Я могу как то изменить это поведение? Чтобы вызывалась функция для фактического типа или я где-то тупанул с паттерном?
Ответ
Потому что всё совершенно не так.
Во-первых интерфейс визитёра должен объявлять методы для всех классов иерархии
public interface FieldVisitor {
Object visit(PresetField field);
Object visit(StringField field);
...
}
Во-вторых родоначальник иерархии объявляет абстрактный метод accept, в котором принимается визитёр
class Field {
...
public abstract void accept(FieldVisitor visitor);
...
}
В-третьих конкретные такие потомки реализуют/переопределяют метод-акцептор таким образом, чтобы вызывался метод визитёра для нужного (своего) класса
class StringField {
...
@Override
public abstract void accept(FieldVisitor visitor) {
visitor.visit(this); // вызов visit(StringField field)
}
...
}
Наконец визитёр может посетить иерархию, предварительно реализовав интерфейс визитёра вызовом акцептора
...
field.accept(new FieldVisitor() {
@Override
Object visit(PresetField field) {
...
}
@Override
Object visit(StringField field) {
...
}
});
...
Благодаря полиморфизму вызывается accept конкретного класса, который в свою очередь вызывает "свой" перегруженный метод визитёра.
Комментариев нет:
Отправить комментарий