# 解释器模式Interpreter
阅读量 loading
# 一、概念
# 1、定义
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
# 2、扩展
为了解释一种语言,而为语言创建的解释器
# 3、类型
行为型
# 4、适用场景
某个特定类型问题发生频率足够高
# 5、优点
语法由很多类表示,容易改变及扩展次“语言”
# 6、缺点
当语法规则数目太多时,增加了系统复杂度
# 7、相关设计模式
- 解释器模式和适配器模式
适配器模式不需要预先知道需要适配的规则,而对于解释器模式需要把规则写好,根据规则进行解释。
# 二、应用
首先声明一个接口,也是解释器模式中最终要的部分:
public interface Interpreter {
int interpret();
}
1
2
3
4
2
3
4
它包含一个解释的方法。
创建一个加法解释器:
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 "+";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
乘法解释器:
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 "*";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
数字解释器:
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 number;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
这个类接受两种类型的构造参数,通过 interpret()
方法返回 int
类型。
在创建一个解释器的类,他有一个运算的方法:
public class ExpressionParser {
private Stack<Interpreter> stack = new Stack<>();
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()));
}
}
return stack.pop().interpret();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
里面用到的一个工具类:
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;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
测试类:
public class Test {
public static void main(String[] args) {
String inputStr = "6 100 11 + *";
ExpressionParser expressionParser = new ExpressionParser();
int result = expressionParser.parse(inputStr);
System.out.println("解释器计算结果:" + result);
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
执行结果:
入栈:6
入栈:100
入栈:11
出栈:11 和 100
应用运算符:111
阶段结果入栈:111
出栈:111 和 6
应用运算符:666
阶段结果入栈:666
解释器计算结果:666
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
类图:
# 三、源码中的应用
# 1、Pattern
正则表达式就是通过 Pattern
解析出来的。
# 2、ExpressionParser
org.springframework.expression
包下的 ExpressionParser
用来解析 EL
语法,它有3个实现类:InternalSpelExpressionParser
、SpelExpressionParser
、TemplateAwareExpressionParser
,下面是演示它的使用方法:
public class SpringTest {
public static void main(String[] args) {
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("100 * 2 + 400 * 1 + 66");
int result = (int) expression.getValue();
System.out.println(result);
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
执行结果:
666
1
← 策略模式Strategy 观察者模式 →