大话设计模式
字体: 16 + -

第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中提供的,当然还有更好、更专业的实现方式。对于终结符,建议采用享元模式来共享它们的拷贝,因为它们要多次重复出现。但是考虑到享元模式的使用局限性,建议还是当你的系统中终结符重复的足够多的时候再考虑享元模式。”