Zer0e's Blog

设计模式之解释器模式

字数统计: 848阅读时长: 3 min
2020/09/05 Share

前言

接下来讲讲解释器模式。

正文

概念

解释器模式属于行为型模式。它实现了一个表达式的接口,用于解释上下文。比如正则表达式解析,SQL解析等等。
这种模式应用上较少,那在框架上用的还是比较多的,比如上文提到了正则表达式,还有XML解析,SQL解析等等都有着应用。

实现

那我们就用一个简单的例子来实现这个模式。
先来讲讲解释器模式中的几个角色:

  • 抽象表达式(AbstractExpression):是所有终结符表达式和非终结符表达式的公共父类。
  • 终结符表达式(TerminalExpression):指的是与终结符相关的表达式。
  • 非终结符表达式(NonterminalExpression):即没有终结符的表达式,通常一个解释器模式中,由少数几个终结符表达式与非终结符表达式构成。
  • Context:上下文,一般是存储需要解释的语句。

比如我要实现一个简易的计算器。
那我们先定义抽象表达式接口Interpreter

1
2
3
public interface Interpreter {
int interpret();
}

然后定义非终结符表达式,这里就是解析数字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class NumberInterpreter implements Interpreter{
private int num;

public NumberInterpreter(int num) {
this.num = num;
}
public NumberInterpreter(String num) {
this.num = Integer.parseInt(num);
}


@Override
public int interpret() {
return this.num;
}
}

然后是终结符表达式,这里就是运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class AddInterpreter implements Interpreter{
private Interpreter first,second;

public AddInterpreter(Interpreter first, Interpreter second) {
this.first = first;
this.second = second;
}

@Override
public String toString() {
return "+";
}

@Override
public int interpret() {
return first.interpret() + second.interpret();
}
}

我们直接写一个客户端调用一下试试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Client {
public static void main(String[] args) {
String express = "2 + 3";
String[] keyWords = express.split(" ");
String operator = "+";
Interpreter[] nums = new Interpreter[2];
int index = 0;
for (String keyword : keyWords){
try {
int tmp = Integer.parseInt(keyword);
nums[index++] = new NumberInterpreter(tmp);
}catch (NumberFormatException e) {
operator = keyword;
}
}
if (operator.equals("+")){
Interpreter add = new AddInterpreter(nums[0],nums[1]);
System.out.println(add.interpret());
}

}
}

我们就简单实现了加法运算,那值得注意的有以下几点:

  • 在main方法中的解析应该转移到工具类当中,客户端应该直接调用工具类。
  • 既然符号是终结符表达式,那么以上的express应该改为后缀表达式”2 3 +”,然后通过栈来求整个表达式的值。

那么以上几点就是我的修改建议,感兴趣的朋友可以接着写下去,实现其他运算,加上工具类的封装。

优缺点

解释器模式的优点在于可扩展性良好,并且十分灵活,当我们新增一个表达式时,原有代码无需修改。
那缺点在于如果语法过于复杂,解析起来会十分麻烦,类的数量会急剧增加,导致难以维护。其次由于解释器模式使用了大量的循环和递归,当面对较复杂语句时执行速度会受到影响。

总结

解释器模式为语言的设计和实现提供了一种解决方案,通过定义表达式来解析语言中的语句,在项目中的使用频率不是很高,但如要实现一门语言或者解析语句,那这个模式就应用的很广泛。

CATALOG
  1. 1. 前言
  2. 2. 正文
    1. 2.1. 概念
    2. 2.2. 实现
    3. 2.3. 优缺点
    4. 2.4. 总结