设计模式之解释器模式

时间:2021-07-09 14:43:25

解释器模式

解释器模式是一种类行为型模式,它主要是用来解释特定语言的特定文法表示,虽然这个在实际生产中不常用到,但是我们学习一下还是有帮助的。

定义

给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

使用场景

当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。而当存在以下情况时该模式的效果最好:
1. 该文法简单对于复杂的文法,文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是更好的选择。它们无需构建抽象语法树即可解释表达式,这样可以节省空间而且还可能节省时间。
2. 效率不是一个关键问题,最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先将它们转换成另外一种形式。例如,正则表达式通常被转换成状态机。但即使在这种情况下,转换器仍可用解释器模式实现,该模式仍是有用的。

结构
设计模式之解释器模式

实现
我们用一个加减乘除的例子来说明一下解释器模式,AbstractExpression接口设计及其实现

public abstract class AbstractExpression {

public abstract int interpret(Context context);

}

public class TerminalExpression extends AbstractExpression {

private int i ;

public TerminalExpression(int a){
i = a;
}

@Override
public int interpret(Context context) {
return i;
}

}

public class Add extends AbstractExpression{

private AbstractExpression left ,right ;

public Add(AbstractExpression left, AbstractExpression right){
this.left = left;
this.right = right;
}

@Override
public int interpret(Context context) {

return left.interpret(context) + right.interpret(context);
}

}

public class Subtract extends AbstractExpression{

private AbstractExpression left ,right ;

public Subtract(AbstractExpression left, AbstractExpression right){
this.left = left;
this.right = right;
}

@Override
public int interpret(Context context) {

return left.interpret(context) - right.interpret(context);
}
}

public class Multiply extends AbstractExpression{

private AbstractExpression left ,right ;

public Multiply(AbstractExpression left, AbstractExpression right){
this.left = left;
this.right = right;
}

@Override
public int interpret(Context context) {

return left.interpret(context) * right.interpret(context);
}
}

public class Division extends AbstractExpression{

private AbstractExpression left ,right ;

public Division(AbstractExpression left, AbstractExpression right){
this.left = left;
this.right = right;
}

@Override
public int interpret(Context context) {

return left.interpret(context)/right.interpret(context);
}
}

Context的设计与实现

public class Context {


private Map<Variable, Integer> valueMap = new HashMap<Variable, Integer>();

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 ;

}
}

public class Variable extends AbstractExpression{

@Override
public int interpret(Context context) {

return context.LookupValue(this);
}

}

我们来测试一下,计算(a*b)/(a-b+2)

public class Client {

private static AbstractExpression aex ;

private static Context con ;

public static void main(String[] args) {
con = new Context();
//设置变量、常量
Variable a = new Variable();
Variable b = new Variable();
TerminalExpression c = new TerminalExpression(2);

//为变量赋值
con.addValue(a , 5);
con.addValue(b , 7);

//运算,对句子的结构由我们自己来分析,构造
aex = new Division(new Multiply(a , b), new Add(new Subtract(a , b) , c));
System.out.println("运算结果为:"+ aex.interpret(con));

}
}

解释器模式提供了一个简单的方式来执行语法,而且容易修改或者扩展语法。一般系统中很多类使用相似的语法,可以使用一个解释器来代替为每一个规则实现一个解释器。而且在解释器中不同的规则是由不同的类来实现的,这样使得添加一个新的语法规则变得简单。解释器模式用来做各种各样的解释器,如正则表达式等的解释器等等。