目录
一、解释器模式的介绍
1、定义
所谓解释器模式就是给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。
解释器模式的角色划分:
- 抽象表达式角色(Abstract Expression):该角色声明一个所有的具体表达式角色都需要实现的抽象接口,该接口主要是一个解释操作interpert()方法。
- 终结符表达式角色(Terminal Expression):该角色实现了抽象表达式角色所要求的接口,文法中的每一个终结符都有一个具体终结表达式与之对应。
- 非终结符表达式角色(Nonterminal Expression):该角色是一个具体角色,文法中的每一条规则都对应一个非终结符表达式类。
- 环境角色(Context):该角色提供解释器之外的一些全局信息。
- 客户端角色(Client):该角色创建一个抽象语法树,调用解释操作。
解释器模式的类图如下:
2、使用场景
- 可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
- 一些重复出现的问题可以用一种简单的语言来进行表达。
- 一个简单语法需要解释的场景。
3、优缺点
(1)优点
- 可扩展性比较好,灵活。
- 增加了新的解释表达式的方式。
- 易于实现简单文法。
(2)缺点
- 需要建大量的类,因为每一种语法都要建一个非终结符的类。
- 解释的时候采用递归调用方法,导致有时候函数的深度会很深,影响效率。
二、解释器模式的实现
场景描述:使用解释器模式完成四则运算。
代码实现:
/**
* 解释器接口
*/
public interface ArithmeticExpression {
/**
* 解释方法
* @param variables
* @return
*/
int interpret(Variables variables);
}
/**
* 终结符表达式
*/
public class Variable implements ArithmeticExpression{
@Override
public int interpret(Variables variables) {
return variables.get(this);
}
}
/**
* 上下文类
*/
public class Variables {
Map<Variable, Integer> v = new HashMap<>();
public void put(Variable variable, int value){
v.put(variable, value);
}
public int get(Variable variable){
return v.get(variable);
}
}
/**
* 加法表达式实现类
*/
public class Plus implements ArithmeticExpression{
ArithmeticExpression left;
ArithmeticExpression right;
public Plus(ArithmeticExpression left, ArithmeticExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Variables variables) {
return left.interpret(variables) + right.interpret(variables);
}
}
/**
* 减法表达式实现类
*/
public class Substract implements ArithmeticExpression{
ArithmeticExpression left;
ArithmeticExpression right;
public Substract(ArithmeticExpression left, ArithmeticExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Variables variables) {
return left.interpret(variables) - right.interpret(variables);
}
}
/**
* 乘法表达式实现类
*/
public class Multiply implements ArithmeticExpression{
ArithmeticExpression left;
ArithmeticExpression right;
public Multiply(ArithmeticExpression left, ArithmeticExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Variables variables) {
return left.interpret(variables) * right.interpret(variables);
}
}
/**
* 除法表达式实现类
*/
public class Divsion implements ArithmeticExpression{
ArithmeticExpression left;
ArithmeticExpression right;
public Divsion(ArithmeticExpression left, ArithmeticExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Variables variables) {
return left.interpret(variables) / right.interpret(variables);
}
}
public class ClientDemo {
public static void main(String[] args) {
Variables variables = new Variables();
Variable x = new Variable();
Variable y = new Variable();
Variable z = new Variable();
variables.put(x, 10);
variables.put(y, 20);
variables.put(z, 30);
//(((30/10)+20)* 10)-10=220
ArithmeticExpression arithmeticExpression = new Substract(new Multiply(x, new Plus(y, new Divsion(z, x))), x);
System.out.println(arithmeticExpression.interpret(variables));
}
}