Хорошо, оба подхода действительны и imo, это действительно зависит от того, хотите ли вы повторно использовать код или нет. Кстати, ваша последняя точка «Con» не является полностью допустимой, так как вам не нужен «внешний файл» для объявления класса. Это вполне может быть внутренний класс ...
Тем не менее, способ, которым я использую Посетителей, выглядит так:
public interface IVisitor<T extends Object> {
public T visit(ClassA element) throws VisitorException;
public T visit(ClassB element) throws VisitorException;
}
public interface IVisitable {
public <T extends Object> T accept(final IVisitor<T> visitor) throws VisitorException;
}
public class MyVisitor implements IVisitor<String> {
private String concat;
public MyVisitor(String concat) {
this.concat = concat;
}
public String visit(ClassA classA) throws VisitorException {
return this.concat + "A";
}
public String visit(ClassB classB) throws VisitorException {
return this.concat + "B";
}
}
public class ClassA implements IVisitable {
public <T> T accept(final IVisitor<T> visitor) throws VisitorException {
return visitor.visit(this);
}
}
public class ClassB implements IVisitable {
public <T> T accept(final IVisitor<T> visitor) throws VisitorException {
return visitor.visit(this);
}
}
// no return value needed?
public class MyOtherVisitor implements IVisitor<Void> {
public Void visit(ClassA classA) throws VisitorException {
return null;
}
public Void visit(ClassB classB) throws VisitorException {
return null;
}
}
Таким образом, посещенные объекты не знают, что посетитель хочет с ними сделать, но они возвращают все, что хочет вернуть посетитель. Ваш посетитель может даже «потерпеть неудачу», создав исключение.
Я написал первую версию этого несколько лет назад, и до сих пор она работала для меня в каждом случае.
Отказ от ответственности : Я только что взломал это вместе, качество (или даже компиляция) не гарантировано. Но вы поняли ...:)