第199章
大b:“来举一个加减乘除的例子吧,实现思路来自于《java与模式》中的例子。每个角色的功能按照上面提到的规范来实现。”
//上下文(环境)角色,使觓shmap来存储变量对应的数值
classcontext
{
privatemapvaluemap=newhashmap();
publicvoidaddvalue(variablex,inty)
{
integeryi=newinteger(y);
valuemap.put(x,yi);
}
publicintlookupvalue(variablex)
{
inti=((integer)valuemap.get(x)).intvalue();
returni;
}
}
//抽象表达式角色,也可以用接口来实现
abstractclassexpression
{
publicabstractintinterpret(contextcon);
}
//终结符表达式角色
classconstantextendsexpression
{
privateinti;
publicconstant(inti)
{
this.i=i;
}
publicintinterpret(contextcon)
{
returni;
}
}
classvariableextendsexpression
{
publicintinterpret(contextcon)
{
//this为调用interpret方法的variable对象
returncon.lookupvalue(this);
}
}
//非终结符表达式角色
classaddextendsexpression
{
privateexpressionleft,right;
publicadd(expressionleft,expressionright)
{
this.left=left;
this.right=right;
}
publicintinterpret(contextcon)
{
returnleft.interpret(con)+right.interpret(con);
}
}
classsubtractextendsexpression
{
privateexpressionleft,right;
publicsubtract(expressionleft,expressionright)
{
this.left=left;
this.right=right;
}
publicintinterpret(contextcon)
{
returnleft.interpret(con)-right.interpret(con);
}
}
classmultiplyextendsexpression
{
privateexpressionleft,right;
publicmultiply(expressionleft,expressionright)
{
this.left=left;
this.right=right;
}
publicintinterpret(contextcon)
{
returnleft.interpret(con)*right.interpret(con);
}
}
classdivisionextendsexpression
{
privateexpressionleft,right;
publicdivision(expressionleft,expressionright)
{
this.left=left;
this.right=right;
}
publicintinterpret(contextcon)
{
try{
returnleft.interpret(con)/right.interpret(con);
}catch(arithmeticexceptionae)
{
system.out.println(“被除数为0!”);
return-11111;
}
}
}
//测试程序,计算(a*b)/(a-b+2)
publicclasstest
{
privatestaticexpressionex;
privatestaticcontextcon;
publicstaticvoidmain(string[]args)
{
con=newcontext();
//设置变量、常量
variablea=newvariable();
variableb=newvariable();
constantc=newconstant(2);
//为变量赋值
con.addvalue(a,5);
con.addvalue(b,7);
//运算,对句子的结构由我们自己来分析,构造
ex=newdivision(newmultiply(a,b),newadd(newsubtract(a,b),c));
system.out.println(运算结果为:+ex.interpret(con));
}
}
大b:“解释器模式并没有说明如何创建一个抽象语法树,因此它的实现可以多种多样,在上面我们是直接在test中提供的,当然还有更好、更专业的实现方式。对于终结符,建议采用享元模式来共享它们的拷贝,因为它们要多次重复出现。但是考虑到享元模式的使用局限性,建议还是当你的系统中终结符重复的足够多的时候再考虑享元模式。”