1. 解释器模式概述
概念
- 给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子
- 例如:使用中文编写出十以内的加减法公式。从表达式计算出整数的过程,称之为解释(interpret)
特点
- 在解释器模式中,不可拆分的最小单元称之为终结表达式;可以被拆分的表达式称之为非终结表达式
- 解释器具有一定的拓展性,当需要添加其他计算符时,可以通过添加 Operator 的子类来完成。但添加后需要按照运算优先级修改计算规则。所以,一个完整的解释器模式是非常复杂的,实际开发中几乎没有需要自定义解释器的情况
应用
- 正则表达式匹配字符串,用到的正则表达式就是一个解释器
Demo
数字和计算符公共的接口
1
2
3interface Expression {
int 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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45public class Number implements Expression {
int number;
public Number(char word) {
switch (word) {
case '零':
number = 0;
break;
case '一':
number = 1;
break;
case '二':
number = 2;
break;
case '三':
number = 3;
break;
case '四':
number = 4;
break;
case '五':
number = 5;
break;
case '六':
number = 6;
break;
case '七':
number = 7;
break;
case '八':
number = 8;
break;
case '九':
number = 9;
break;
default:
break;
}
}
public int interpret() {
return number;
}
}将计算符提取出共同的抽象父类
1
2
3
4
5
6
7
8
9abstract class Operator implements Expression {
Expression left;
Expression right;
Operator(Expression left, Expression right) {
this.left = left;
this.right = right;
}
}加法类
1
2
3
4
5
6
7
8
9
10
11class Add extends Operator {
Add(Expression left, Expression right) {
super(left, right);
}
public int interpret() {
return left.interpret() + right.interpret();
}
}减法类
1
2
3
4
5
6
7
8
9
10
11class Sub extends Operator {
Sub(Expression left, Expression right) {
super(left, right);
}
public int interpret() {
return left.interpret() - right.interpret();
}
}计算类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class Calculator {
int calculate(String expression) {
Stack<Expression> stack = new Stack<>();
for (int i = 0; i < expression.length(); i++) {
char word = expression.charAt(i);
switch (word) {
case '加':
stack.push(new Add(stack.pop(), new Number(expression.charAt(++i))));
break;
case '减':
stack.push(new Sub(stack.pop(), new Number(expression.charAt(++i))));
break;
default:
stack.push(new Number(word));
break;
}
}
return stack.pop().interpret();
}
}测试类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public class Client {
@Test
public void test() {
Calculator calculator = new Calculator();
String expression1 = "一加一";
String expression2 = "一加一加一";
String expression3 = "二加五减三";
String expression4 = "七减五加四减一";
String expression5 = "九减五加三减一";
// 输出: 一加一 等于 2
System.out.println(expression1 + " 等于 " + calculator.calculate(expression1));
// 输出: 一加一加一 等于 3
System.out.println(expression2 + " 等于 " + calculator.calculate(expression2));
// 输出: 二加五减三 等于 4
System.out.println(expression3 + " 等于 " + calculator.calculate(expression3));
// 输出: 七减五加四减一 等于 5
System.out.println(expression4 + " 等于 " + calculator.calculate(expression4));
// 输出: 九减五加三减一 等于 6
System.out.println(expression5 + " 等于 " + calculator.calculate(expression5));
}
}