书城计算机网络大话设计模式
8183300000199

第199章 8 加减乘除

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