大B:“来举一个加减乘除的例子吧,实现思路来自于《java与模式》中的例子。每个角色的功能按照上面提到的规范来实现。”
//上下文(环境)角色,使用HashMap来存储变量对应的数值
class Context
{
private Map valueMap=new HashMap();
public void addValue(Variable x,int y)
{
Integer yi=new Integer(y);
valueMap。put(x,yi);
}
public int LookupValue(Variable x)
{
int i=((Integer)valueMap。get(x))。intValue();
return i;
}
}
//抽象表达式角色,也可以用接口来实现
abstract class EXPression
{
public abstract int interpret(Context con);
}
//终结符表达式角色
class Constant extends Expression
{
private int i;
public Constant(int i)
{
this。i=i;
}
public int interpret(Context con)
{
return i;
}
}
class Variable extends Expression
{
public int interpret(Context con)
{
//this为调用interpret方法的Variable对象
return con。LookupValue(this);
}
}
//非终结符表达式角色
class Add extends Expression
{
private Expression left,right;
public Add(Expression left,Expression right)
{
this。left=left;
this。right=right;
}
public int interpret(Context con)
{
return left。interpret(con) right。interpret(con);
}
}
class SuBTract extends Expression
{
private Expression left,right;
public Subtract(Expression left,Expression right)
{
this。left=left;
this。right=right;
}
public int interpret(Context con)
{
return left。interpret(con)-right。interpret(con);
}
}
class Multiply extends Expression
{
private Expression left,right;
public Multiply(Expression left,Expression right)
{
this。left=left;
this。right=right;
}
public int interpret(Context con)
{
return left。interpret(con)*right。interpret(con);
}
}
class Division extends Expression
{
private Expression left,right;
public Division(Expression left,Expression right)
{
this。left=left;
this。right=right;
}
public int interpret(Context con)
{
try{
return left。interpret(con)/right。interpret(con);
}catch(ArithmeticException ae)
{
System。out。println(“被除数为0!”);
return-11111;
}
}
}
//测试程序,计算(a*b)/(a-b 2)
public class Test
{
private static Expression ex;
private static Context con;
public static void main(String[]args)
{
con=new Context();
//设置变量、常量
Variable a=new Variable();
Variable b=new Variable();
Constant c=new Constant(2);
//为变量赋值
con。addValue(a,5);
con。addValue(b,7);
//运算,对句子的结构由我们自己来分析,构造
ex=new Division(new Multiply(a,b),new Add(new Subtract(a,b),c));
System。out。println(运算结果为: ex。interpret(con));
}
}
大B:“解释器模式并没有说明如何创建一个抽象语法树,因此它的实现可以多种多样,在上面我们是直接在Test中提供的,当然还有更好、更专业的实现方式。对于终结符,建议采用享元模式来共享它们的拷贝,因为它们要多次重复出现。但是考虑到享元模式的使用局限性,建议还是当你的系统中终结符重复的足够多的时候再考虑享元模式。”