У меня есть выражение, сделанное составной шаблон дизайна:Оценка дерева выражений с помощью Visitor
interface TreeExpression{
void accept(Visitor visitor);
}
abstract class Operator{
TreeExpression childA;
TreeExpression childB;
Operator(TreeExpression a, TreeExpression b){
this.childA = a;
this.childB = b;
}
}
class PlusTreeExpression extends Operator implements TreeExpression{
public PlusTreeExpression(TreeExpression a, TreeExpression b) {
super(a, b);
}
public void accept(Visitor visitor) {
this.childA.accept(visitor);
visitor.visit(this);
this.childB.accept(visitor);
}
}
class MultiplyTreeExpression extends Operator implements TreeExpression{
public MultiplyTreeExpression(TreeExpression a, TreeExpression b) {
super(a, b);
}
public void accept(Visitor visitor) {
this.childA.accept(visitor);
visitor.visit(this);
this.childB.accept(visitor);
}
}
class IntegerNode implements TreeExpression{
Integer value;
IntegerNode(int v){
this.value = v;
}
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
и посетители для получения строки из выражения:
interface Visitor{
void visit(PlusTreeExpression tree);
void visit(MultiplyTreeExpression tree);
void visit(IntegerNode node);
}
class PrintVisitor implements Visitor{
public StringBuffer result = new StringBuffer();
public void visit(IntegerNode node) {
result.append(node.value);
}
public void visit(PlusTreeExpression tree) {
result.append("+");
}
public void visit(MultiplyTreeExpression tree) {
result.append("*");
}
Это visitore работ и теперь я пытаюсь сделать посетитель для оценки выражения, но здесь у меня проблема. Я пробовал несколько способов, как это сделать, но я не знаю, как получить значение из дочернего дерева в корневой каталог без изменения существующего кода.
+1: Хотя это потребует некоторой ревизии (вы используете посещение, как если бы оно возвращало значение в этом коде), перемещение итерации к посетителю явно способ сделать это проще. –
@DonRoby, возвращающее значение, казалось самым простым способом справиться с этим для меня из-за рекурсивного характера. Вы можете изменить его, чтобы использовать переменные экземпляра, но IMHO, что сделает код менее читаемым. В качестве альтернативы, если вы хотите сохранить окончательное значение, вы можете обернуть посетителя объектом, который кэширует его. –
Фактически, как показано на рисунке, ваш код не будет компилироваться, поскольку методы посещения возвращают значение, но объявляются как void. –