第199章(1 / 1)

大话设计模式 吴强 1251 字 2个月前

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