一、定义
给定一种语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解析语言中的句子。
简单理解:为了解释一种语言,而为语言创建的解释器。
C#代码,Java代码的编译器就相当于一个解释器。
类型: 行为型
二、适用场景
1、某个特定类型问题发生频率足够高
如程序中有很多日志,对日志进行解析就是解析器。日常使用比较少(低频)。
三、解释器-优点
语法由很多类表示,容易改变及扩展此“语言”
四、解释器模式-缺点
1、当语法规则数目太多时,增加了系统的复杂度
规则太多,每个规则都要写一个类。
五、解释器模式-相关设计模式
1、解释器模式和适配器模式
适配器模式是不需要预先知道要适配的规则
解析器模式把规则写好,根据规则执行解释。
六、Coding
1、Interpreter 接口
public interface Interpreter {
//解释
int interpret();
}
2、 加法解释器 AddInterprete
/**
* 加法解释器
*/
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 firstExpression.interpret() + 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 firstExpression.interpret() * secondExpression.interpret();
}
@Override
public String toString() {
return "*";
}
}
4、数字解释器NumberInterprete
/**
* 数字解释器
*/
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、工具类OperatorUtil
public class OperatorUtil {
/**
* 是否是操作符
* @param symbol
* @return
*/
public static boolean isOperator(String symbol){
return ( "+".equals(symbol) || "*".equals(symbol));
}
public static Interpreter getExpressionObject(Interpreter firstExpression, Interpreter secondExpression, String symbol){
if("+".equals(symbol)){
return new AddInterpreter(firstExpression, secondExpression);
}else if("*".equals(symbol)){
return new MultiInterpreter(firstExpression, secondExpression);
}
return null;
}
}
6、LarryExpressionParser 类
public class LarryExpressionParser {
private Stack<Interpreter> stack = new Stack<>();
public int parse(String str){
String[] strInemArray = str.split(" ");
for(String item : strInemArray){
if(!OperatorUtil.isOperator(item)){
Interpreter numberExpression = new NumberInterpreter(item);
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, item);
System.out.println(String.format("应用运算符: %s", operator));
int result = operator.interpret();
NumberInterpreter resultExpress = new NumberInterpreter(result);
stack.push(resultExpress);
System.out.println(String.format("阶段结果入栈: %d", resultExpress.interpret()));
}
}
int result = stack.pop().interpret();
return result;
}
}
7、测试类
public class Test {
public static void main(String[] args) {
String input = "6 100 11 + *"; //(100+11)*6=666
LarryExpressionParser larryExpressionParser = new LarryExpressionParser();
int result = larryExpressionParser.parse(input);
System.out.println("解释器计算结果:" + result);
}
}
8、测试结果

9、UML图

七、在源码中的应用
1、Pattern正则

2、Spring EL表达式
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
public class SpringTest {
public static void main(String[] args) {
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("100 * 3 + 500 * 2 + 6 * 5");
int result = (Integer)expression.getValue();
System.out.println(result);
}
}
结果如下图
