解释器设计模式(Interpreter Pattern)

描述: 解释器设计模式就是提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。

核心思想: 对于一些固定语法构建一个解释 语法 的解释器

使用场景:

  • 可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
  • 一些重复出现的问题可以用一种简单的语言来进行表达。
  • 一个简单语法需要解释的场景。

解释器设计模式的优点:

  • 可扩展性比较好,灵活。
  • 增加了新的解释表达式的方式。
  • 易于实现简单文法。

解释器设计模式的缺点:

  • 可利用场景比较少。
  • 对于复杂的文法比较难维护。
  • 解释器模式会引起类膨胀。
  • 解释器模式采用递归调用方法。

示例:

  • 抽象出 表达式接口
1
2
3
interface Interpreter {
int interpret();
}
  • 相加表达式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 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 "+";
}
}

  • 相乘表达式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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 "*";
}
}

  • 数值表达式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 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;
}
}
  • 格式化
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
class ExpressionParser {

private Stack<Interpreter> stack = new Stack<>();

public int parse (String expression) {
String[] itemArray = expression.split(" ");
for (String symbol : itemArray) {
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.getExpression(firstExpression, secondExpression, symbol);
System.out.println(String.format("应用运算符: %s", operator));
int result = operator.interpret();
NumberInterpreter numberInterpreter = new NumberInterpreter(result);
stack.push(numberInterpreter);
System.out.println(String.format("阶段结果入栈: %d", result));
}
}
return stack.pop().interpret();
}
}

  • 工具类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
lass OperatorUtil {

public static boolean isOperator(String symbol) {
return (symbol.equals("+") || symbol.equals("*"));
}

public static Interpreter getExpression(Interpreter first,
Interpreter second,
String symbol) {
switch (symbol) {
case "+":
return new AddInterpreter(first, second);
case "*":
return new MultiInterpreter(first, second);
default:
return null;
}
}
}
  • 调用
1
2
3
4
5
6
public static void main(String[] args) {
String input = "6 100 11 + *";
ExpressionParser parser = new ExpressionParser();
int result = parser.parse(input);
System.out.println("解释器运算结果:" + result);
}