解释器
- 是一种不常用的设计模式
- 用于描述如何构成一个简单的语言解释器,主要用于使用面向对象语言开发的解释器和解释器设计
- 当我们需要开发一种新的语言时,可以考虑使用解释器模式
- 尽量不要使用解释器模式,后期维护会有很大麻烦。在项目中,可以使用jruby、groovy、java的js引擎来替代解释器的作用,弥补java语言的不足。
开发中常见的场景
- EL表达式的处理
- 正则表达式解释器
- SQL语法的解释器
- 数学表达式解释器
举例代码实现
- 解析和执行数学表达式
输入"5+4*5-8/4",输出"23" - 抽象解释器接口
java
/**
* 抽象解释器接口
*/
public interface Expression {
int interpret(Context context);
}
- 终结符表达式
java
/**
* 数值表达式---终结符表达式
*/
public class NumberExpression implements Expression{
private Integer number;
public NumberExpression(Integer number) {
super();
this.number = number;
}
@Override
public int interpret(Context context) {
return number;
}
}
/**
* 运算符号表达式---终结符表达式
* symbol:
* 1:加
* 2:减
* 3:乘
* 4:除
*/
public class SymbolExpression implements Expression {
private int symbol;
public SymbolExpression(int symbol) {
super();
this.symbol = symbol;
}
@Override
public int interpret(Context context) {
return symbol;
}
}
- 非终结符表达式
java
/**
* 加法表达式------加法表达式也是数值表达式的一种
*/
public class AdditionExpression extends NumberExpression{
private NumberExpression left;
private NumberExpression right;
public AdditionExpression(NumberExpression left, NumberExpression right) {
super(1);
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) + right.interpret(context);
}
}
/**
* 减法表达式---减法表达式也是数值表达式的一种
*/
public class SubtractExpression extends NumberExpression{
private NumberExpression left;
private NumberExpression right;
public SubtractExpression(NumberExpression left, NumberExpression right) {
super(2);
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) - right.interpret(context);
}
}
/**
* 乘法表达式------乘法表达式也是数值表达式的一种
*/
public class MultiplicationExpression extends NumberExpression{
private NumberExpression left;
private NumberExpression right;
public MultiplicationExpression(NumberExpression left, NumberExpression right) {
super(3);
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) * right.interpret(context);
}
}
/**
* 除法表达式------除法表达式也是数值表达式的一种
*/
public class DivisionExpression extends NumberExpression{
private NumberExpression left;
private NumberExpression right;
public DivisionExpression(NumberExpression left, NumberExpression right) {
super(4);
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) / right.interpret(context);
}
}
- 上下文类(context)
java
public class Context {
Expression expression;
public Context(String expression) {
Expression parse = init(expression);
this.expression = parse;
}
public int calculate(){
return this.expression.interpret(this);
}
private Expression init(String expression) {
LinkedList<Expression> linkedList = new LinkedList<Expression>();
int num = 0;
for(int i=0;i<expression.length();i++) {
char ati;
if((ati=expression.charAt(i))>='0' && ati<='9') {
num = num*10 + (ati-'0');
}else {
addNum(linkedList, num);
SymbolExpression symbolExpression = null;
switch (ati) {
case '+':
symbolExpression = new SymbolExpression(1);
break;
case '-':
symbolExpression = new SymbolExpression(2);
break;
case '*':
symbolExpression = new SymbolExpression(3);
break;
case '/':
symbolExpression = new SymbolExpression(4);
break;
default:
break;
}
num = 0;
linkedList.addLast(symbolExpression);
}
}
addNum(linkedList, num);
return getExpression(linkedList);
}
/**
* 添加num
* @param linkedList
* @param num
*/
private void addNum(LinkedList<Expression> linkedList,int num) {
NumberExpression numberExpression = new NumberExpression(num);
if(!linkedList.isEmpty()) {
Expression symbol = linkedList.pollLast();
if(symbol.interpret(this)==1 || symbol.interpret(this)==2) {
linkedList.addLast(symbol);
}else {
NumberExpression left = (NumberExpression)linkedList.pollLast();
NumberExpression right = numberExpression;
if(symbol.interpret(this)==3) {
numberExpression = new MultiplicationExpression(left, right);
}else {
numberExpression = new DivisionExpression(left, right);
}
}
}
linkedList.add(numberExpression);
}
/**
* 获取Expression
* @param linkedList
* @return
*/
private Expression getExpression(LinkedList<Expression> linkedList){
SymbolExpression symbolExpression = null;
NumberExpression left = null;
while(!linkedList.isEmpty()){
Expression tempExpression = linkedList.pollFirst();
if(tempExpression instanceof SymbolExpression){
symbolExpression = (SymbolExpression)tempExpression;
}else{
if(left==null){
left = (NumberExpression)tempExpression;
}else{
NumberExpression right = (NumberExpression)tempExpression;
switch (symbolExpression.interpret(this)) {
case 1:
left = new AdditionExpression(left, right);
break;
case 2:
left = new SubtractExpression(left, right);
break;
case 3:
left = new MultiplicationExpression(left, right);
break;
case 4:
left = new DivisionExpression(left, right);
break;
default:
break;
}
}
}
}
return left;
}
}
- 客户端调用
java
public static void main(String[] args) {
Context context = new Context("33+12*9+42/2+6/3");
int calculate = context.calculate();
System.out.println("计算结果:calculate:"+calculate);
}
- 结果
更多设计模式学习:
设计模式持续更新中...