| 
 (wang hailong) 
本文给出一个Visitor Pattern的简单例子的源代码,并给出相关解释。一个使用Visitor Pattern处理四则运算的例子。源代码通过编译,正确运行。java calculate.TestMain 
其他的资料里,也有相似的例子。比如,http://www.umlchina.com的“模式”栏目。我这里给出一个最简化的例子,为了对应我的另一篇关于Visitor Pattern的文章。 
程序包括一个四则运算揭示器Visitor,用来解析表达式树。 
被访问者的类包括:加法表达式,减法表达式,单值表达式。(为了简化问题,没有引入乘除表达式。) 
首先,我们来看被访问者的类的定义。 
Expression.java  表达式类公用接口,所有的表达式类都要实现这个接口 
package calculate; 
public interface Expression { 
  public int accept(Visitor visitor); 
} 
  
UnaryExpression.java 单值表达式 
package calculate; 
public class UnaryExpression implements Expression{ 
  protected int value; 
  public int getValue(){ 
    return value; 
  } 
  public UnaryExpression(int aValue) { 
    value = aValue; 
  } 
  public int accept(Visitor visitor) { 
    return visitor.visit(this); 
  } 
} 
BinaryExpression.java 二元表达式 
package calculate; 
public abstract class BinaryExpression implements Expression{ 
  /** 
   * left node and right node 
   */ 
  protected Expression leftNode; 
  protected Expression rightNode; 
  /** 
   * default contructor 
   */ 
  public BinaryExpression() { 
  } 
  /** 
   * get left node 
   */ 
  public Expression getLefNode(){ 
    return leftNode; 
  } 
  /** 
   * get right node 
   */ 
  public Expression getRightNode(){ 
    return rightNode; 
  } 
  /** 
   * implements Expression interface 
   */ 
  public abstract int accept(Visitor visitor); 
}; 
  
AddExpression.java 加法表达式 
package calculate; 
public class AddExpression extends BinaryExpression { 
  public AddExpression(Expression aLeftNode, Expression aRightNode) { 
    leftNode = aLeftNode; 
    rightNode = aRightNode; 
  } 
  public int accept(Visitor visitor) { 
    return visitor.visit(this); 
  } 
} 
SubExpression.java 减法表达式 
package calculate; 
public class SubExpression extends BinaryExpression { 
  public SubExpression(Expression aLeftNode, Expression aRightNode) { 
    leftNode = aLeftNode; 
    rightNode = aRightNode; 
  } 
  public int accept(Visitor visitor){ 
    return visitor.visit(this); 
  } 
} 
  
以上就是表达式部分所有的代码了。下面是Visitor的代码。 
Visitor.java 四则运算揭示器Visitor,用来解析表达式树 
package calculate; 
public class Visitor { 
  /** 
   * default constructor 
   */ 
  public Visitor(){ 
  } 
  /** 
   * entry point 
   * @param expression 
   */ 
  public int visit(Expression expression){ 
    return expression.accept(this); 
  } 
  // 处理单元表达式 
  public int visit(UnaryExpression expression){ 
    int value = expression.getValue(); 
    return value; 
  } 
  // 处理加法表达式 
  public int visit(AddExpression expression){ 
    Expression leftNode = expression.getLefNode(); 
    Expression rightNode = expression.getRightNode(); 
  
    // please pay specail attention to thses lines 
    int leftValue = leftNode.accept(this); 
    int rightValue = rightNode.accept(this); 
  
    int result = leftValue + rightValue; 
    System.out.println(leftValue + " + " + rightValue + " = "  + result); 
    return result; 
  } 
  // 处理减法表达式 
  public int visit(SubExpression expression){ 
    Expression leftNode = expression.getLefNode(); 
    Expression rightNode = expression.getRightNode(); 
  
    // please pay specail attention to thses line 
    int leftValue = leftNode.accept(this); 
    int rightValue = rightNode.accept(this); 
  
    int result = leftValue - rightValue; 
    System.out.println(leftValue + " - " + rightValue + " = "  + result); 
    return result; 
  } 
} 
  
我们看到,Visitor遍历表达式树,进行运算。表达式是被访问者,不做任何运算,只提供本身的类型信息和结构信息。 
下面是测试程序。 
TestMain.java 首先,生成一个表达式树,然后用Visitor访问这个表达式树,进行运算 
package calculate; 
public class TestMain { 
  public static void main(String[] args) { 
    Visitor visitor = new Visitor(); 
  
    //生成一个表达式树 10 - (6 + 3) 
    UnaryExpression ten = new UnaryExpression(11); 
    UnaryExpression six = new UnaryExpression(6); 
    UnaryExpression three = new UnaryExpression(3); 
  
    BinaryExpression six_add_three = new AddExpression(six, three); 
    BinaryExpression ten_sub_6_3 = new SubExpression(ten, six_add_three); 
  
    // 用Visitor访问这个表达式树,进行运算 
    int result = visitor.visit(ten_sub_6_3); 
  } 
} 
  
输出结果为: 
6 + 3 = 9 
11 - 9 = 2 
  
以上这个例子很容易扩展,增加乘除运算。继承BinaryExpression. 
   
 
  |