解释器原理:将复杂的问题简单化,模块化,分离实现,解释执行。
例如一段密电,首先要看哪里是终结点。那么两个终结点之间的一段密文就是一句话。整篇密电就是由多个一句话构成。解释器模式就是要把这篇密文拆成每句话来解释。
类图
简单实现
相当于AbstractExpression 抽象解释器
public abstract class ArithmeticExpression {
/**
* 抽象的解析方法
* 具体的解析逻辑由具体的子类实现
* @return
*/
public abstract int interpreter();
}
相当于TernimalExpression 终点解释器
因为遇到数字就要和前面的值做加减乘除的操作,所以遇到了数字就意味着前面已经可以计算。
/**
* 数字解释器
*/
public class NumExpression extends ArithmeticExpression {
private int num;
public NumExpression(int num) {
this.num = num;
}
public int interpreter() {
return num;
}
}
相当于NonTernimalExpression 非终点解释
遇到加号就要把前面的部分和下一个数字构成一个可以运算的整体。
/**
*运算符号解释器
*/
public abstract class OperatorExpression extends ArithmeticExpression{
//声明两个成员变量,存储运算符号两边的数字解析器
protected ArithmeticExpression expression1,expression2;
public OperatorExpression(ArithmeticExpression expression1,ArithmeticExpression expression2){
this.expression1 = expression1;
this.expression2 = expression2;
}
}
/**
*加法运算解释器
*/
public class AdditionExpression extends OperatorExpression {
public AdditionExpression(ArithmeticExpression expression1,
ArithmeticExpression expression2) {
super(expression1, expression2);
}
public int interpreter() {
return expression1.interpreter() + expression2.interpreter();
}
}
下面是具体处理解释器逻辑的代码。判断一个字符串应该怎么去解释。
public class Caculator {
//声明一个Stack栈存储并操作所有的解释器
private Stack<ArithmeticExpression> stack = new Stack();
public Caculator(String expression) {
//声明两个ArithMEthicExpression类型的临时变量,存储运算符左右两边的数字解释器
ArithmeticExpression expression1,expression2;
//循环遍历字符串
for(int i=0;i<expression.length();i++){
String m =String.valueOf(expression.charAt(i)) ;
switch (m) {
case "+"://如果是加号
//将栈中的解释器弹出作为运算符号左边的解释器
expression1 = stack.pop();
//同时将运算符号数组下标下一个元素构成为一个数字解释器
expression2 = new NumExpression(Integer.valueOf(String.valueOf(expression.charAt(++i))));
//通过上面两个数字解释器构造加法解释器
stack.push(new AdditionExpression(expression1, expression2));
break;
default://如果为数字
stack.push(new NumExpression(Integer.valueOf(m)));
break;
}
}
}
public int calculate(){
return stack.pop().interpreter();
}
}
这里没有对字符串的格式做筛选。比如 1+3就能正常算。但是任意的多位数就不行。比如1+19。因为主要是看解释器的模式,所以就忽略了。
return stack.pop().interpreter();
这一行用了递归,虽然最后是AdditionExpression和NumExpression的和。但是其实会调用Addition最深的两个NumExpression。然后在一层一层的相加。参照图:
public class Client {
public static void main(String[] args) {
Caculator caculator = new Caculator("1+3+5+2");
System.out.println(caculator.calculate());
}
}