1️⃣概念
定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子(为了解释一种语言,而为语言创建的解释器).
类型:行为型
2️⃣适用场景
某个特定类型问题的发生频率足够高的时候(例如系统中的日志服务);
3️⃣优点
语法有很多类表示,容易改变及扩展此"语言"
4️⃣缺点
当语法规则数目太多时,增加了系统的复杂度;
5️⃣解释器模式Coding
1 先来了解一下我们要实现一个什么样的功能;
public class Test {
public static void main(String[] args) {
String inputStr="6 100 11 + *";
TestExpressionParser expressionParser=new TestExpressionParser();
int result=expressionParser.parse(inputStr);
System.out.println("解释器计算结果: "+result);
}
}

我们先自定义一个字符串(6 100 11 + *)两个字符串之间用空格隔开,先计算100 + 11,然后其结果在乘以6得到最终的结果;
2 声明Interpreter接口
public interface Interpreter {
int interpret();
}
3 编写加法解释器AddInterpreter
public class AddInterpreter implements Interpreter {
private Interpreter firstExpression,secondExpression;
public AddInterpreter(Interpreter firstExpression, Interpreter secondExpression){
this.firstExpression=firstExpression;
this.secondExpression=secondExpression;
}
@Override
public int interpret(){
return this.firstExpression.interpret()+this.secondExpression.interpret();
}
@Override
public String toString(){
return "+";
}
}
3 编写乘法解释器MultiInterpreter
public class MultiInterpreter implements Interpreter {
private Interpreter firstExpression,secondExpression;
public MultiInterpreter(Interpreter firstExpression, Interpreter secondExpression){
this.firstExpression=firstExpression;
this.secondExpression=secondExpression;
}
@Override
public int interpret(){
return this.firstExpression.interpret() * this.secondExpression.interpret();
}
@Override
public String toString(){
return "*";
}
}
4 编写NumberInterpreter实现类
public class NumberInterpreter implements Interpreter {
private int number;
public NumberInterpreter(int number){
this.number=number;
}
public NumberInterpreter(String number){
this.number=Integer.parseInt(number);
}
@Override
public int interpret(){
return this.number;
}
}
5 编写TestExpressionParser
public class TestExpressionParser {
private Stack<Interpreter> stack = new Stack<Interpreter>();
public int parse(String str) {
String[] strItemArray = str.split(" ");
for (String symbol : strItemArray) {
if (!OperatorUtil.isOperator(symbol)) {
Interpreter numberExpression = new NumberInterpreter(symbol);
stack.push(numberExpression);
System.out.println(String.format("入栈: %d", numberExpression.interpret()));
} else {
//是运算符号,可以计算
Interpreter firstExpression = stack.pop();
Interpreter secondExpression = stack.pop();
System.out.println(String.format("出栈: %d 和 %d",
firstExpression.interpret(), secondExpression.interpret()));
Interpreter operator = OperatorUtil.getExpressionObject(firstExpression, secondExpression, symbol);
System.out.println(String.format("应用运算符: %s", operator));
int result = operator.interpret();
NumberInterpreter resultExpression = new NumberInterpreter(result);
stack.push(resultExpression);
System.out.println(String.format("阶段结果入栈: %d", resultExpression.interpret()));
}
}
int result = stack.pop().interpret();
return result;
}
}
6 编写工具类OperatorUtil
public class OperatorUtil {
public static boolean isOperator(String symbol) {
return (symbol.equals("+") || symbol.equals("*"));
}
public static Interpreter getExpressionObject(Interpreter firstExpression, Interpreter secondExpression, String symbol) {
if (symbol.equals("+")) {
return new AddInterpreter(firstExpression, secondExpression);
} else if (symbol.equals("*")) {
return new MultiInterpreter(firstExpression, secondExpression);
}
return null;
}
}
7 UML类图![]()
6️⃣解释器源码解析-jdk+spring
jdk : pattern![]()
spring : org.springframework.expression.ExpressionParser![]()
Spring的解释器可以使用以下代码进行测试
public class SpringTest {
public static void main(String[] args) {
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("100 * 2 + 400 * 1 + 66");
int result = (Integer) expression.getValue();
System.out.println(result);
}
}

网友评论