1、概念
解释器模式给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子,属于行为型模式。但其在实际的系统开发中使用的很少,因为他会引起效率、性能以及维护等问题
2、模式结构
- 抽象解释器(AbstractExpression):声明一个所有的具体表达式角色都需要实现的抽象接口。这个接口主要是一个interpret()方法,称作解释操作
- 终结符表达式(TerminalExpression):实现了抽象表达式角色所要求的接口,主要是一个interpret()方法;文法中的每一个终结符都有一个具体终结表达式与之相对应
- 非终结符表达式(NonterminalExpression):文法中的每一条规则都需要一个具体的非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键
- 环境类(Context):用来存放文法中各个终结符所对应的具体值
3、使用场景
- 可以将一个需要解释执行的语言中的句子表示为一个抽象语法树
- 一些重复出现的问题可以用一种简单的语言来进行表达
- 一个简单语法需要解释的场景
4、优缺点
优点:
- 可扩展性比较好,灵活
- 增加了新的解释表达式的方式
- 易于实现文法
缺点:
- 可利用场景比较少
- 对于复杂的文法比较难维护
- 解释器模式会引起类膨胀
- 解释器模式采用递归调用方法
5、实例
定义环境类Context
public class Context {
private Map<Expression, Integer> valueMap;
public Context() {
this.valueMap = new HashMap<>();
}
public void addValue(Expression ex, Integer value) {
valueMap.put(ex, value);
}
public int getValue(Expression ex) {
if (valueMap.containsKey(ex)) {
return valueMap.get(ex);
}
return 0;
}
}
定义抽象解释器Expression
public interface Expression {
int interpreter(Context context);
}
定义终结符表达式TerminalExpression
public class TerminalExpression implements Expression {
private int number;
public TerminalExpression(int number) {
this.number = number;
}
@Override
public int interpreter(Context context) {
return number;
}
}
定义终结符表达式VariableExpression
public class VariableExpression implements Expression {
@Override
public int interpreter(Context context) {
return context.getValue(this);
}
}
定义非终结符表达式MinusExpression
public class MinusExpression implements Expression {
private Expression left;
private Expression right;
public MinusExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpreter(Context context) {
return left.interpreter(context) - right.interpreter(context);
}
}
定义非终结符表达式AddExpression
public class AddExpression implements Expression {
private Expression left;
private Expression right;
public AddExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpreter(Context context) {
return left.interpreter(context) + right.interpreter(context);
}
}
客户端使用
Context context = new Context();
VariableExpression x = new VariableExpression();
VariableExpression y = new VariableExpression();
TerminalExpression terminal = new TerminalExpression(100);
context.addValue(x, 20);
context.addValue(y, 50);
Expression expression = new AddExpression(new MinusExpression(x, y), terminal);
System.out.println("Result = " + expression.interpreter(context));