Mar*_*čko 3 java oop design-patterns 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);
}
}
Run Code Online (Sandbox Code Playgroud)
和访问者从表达式获取字符串:
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("*");
}
Run Code Online (Sandbox Code Playgroud)
这个访问工作,现在我正在尝试访问评估表达,但在这里我有一个问题.我尝试了几种方法,但我不知道如何在不改变现有代码的情况下从子树获取值到root.
据我所知,这里的问题是你定义了如何在树本身而不是访问者中遍历树.虽然这可能是一种有效的方法(设计模式确实有变化),但我认为在这种情况下,最好将树结构与遍历顺序(预订,有序,后顺序)分离.事实上,在教授这种模式时,典型的练习是写三个访客,每个访客进行不同的遍历.
在你的情况下,我会:
像表达式一样将表达式表示为树,但是从表单中删除接受遍历的部分.在您的代码中,接受看起来像:
public void accept(Visitor visitor)
{
visitor.visit(this);
}
Run Code Online (Sandbox Code Playgroud)为节点的子节点定义公共getter,以便访问者可以访问它们(getChildA(),getChildB()和getValue()).
根据您需要的遍历类型编写访问者.为了评估表达式,您通常会使用下订单,同时打印您可以按顺序使用的表达式(如您的示例中所示).因此,为了评估表达式,您将看到如下所示的内容:
class EvalVisitor implements Visitor{
public Integer visit(IntegerNode node) {
return node.getValue();
}
public Integer visit(PlusTreeExpression tree) {
return this.visit(tree.getChildA()) + this.visit(tree.getChildB());
}
public Integer visit(MultiplyTreeExpression tree) {
return this.visit(tree.getChildA()) * this.visit(tree.getChildB());
}
}
Run Code Online (Sandbox Code Playgroud)HTH