Java设计模式--解释器模式

解释器模式

给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

Interpreter Pattern

Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.

类图

模式的结构与使用

解释器模式的结构中包括四个角色。

  • 抽象表达式(AbstractExpression):该角色为一个接口,负责定义抽象的解释操作。
  • 终结符表达式(TerminalExpression):实现AbstractExpression接口的类。该类将接口中的解释器操作实现为与文法中的终结符相关联的操作,即文法中的每个终结符需要一个TerminalExpression类。
  • 非终结符表达式(NonterminalExpression):实现AbstractExpression接口的类。文法中的每一条规则R::=R1R2…Rn都需要一个NonterminalExpression类。NonterminalExpression类为文法中的非终结符号实现解释操作,该解释操作通常使用递归用表示Ri到Rn的那些对象的解释操作。
  • 上下文(Context):包含解释器之外的一些全局信息。

简单的例子

Node的接口类Dog.java

1
2
3
4
5
6
package Interpreter;
public interface Node {
public void parse(Context text);
public void execute();
}

Context的类Context.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package Interpreter;
import java.util.StringTokenizer;
public class Context {
StringTokenizer tokenizer;
String token;
public Context(String text) {
setContext(text);
}
public void setContext(String text) {
tokenizer = new StringTokenizer(text);
}
String nextToken() {
if (tokenizer.hasMoreTokens()) {
token = tokenizer.nextToken();
} else
token = "";
return token;
}
}

Node的实现类SubjectPronounOrNounNode.java

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
package Interpreter;
public class SubjectPronounOrNounNode implements Node {
String[] word = {"You", "He", "Teacher", "Student"};
String token;
boolean boo;
@Override
public void parse(Context context) {
token = context.nextToken();
int i = 0;
for (; i < word.length; i++) {
if (token.equalsIgnoreCase(word[i])) {
boo = true;
break;
}
}
if (i == word.length) {
boo = false;
}
}
@Override
public void execute() {
if (boo) {
if (token.equalsIgnoreCase(word[0]))
System.out.print("你");
if (token.equalsIgnoreCase(word[1]))
System.out.print("他");
if (token.equalsIgnoreCase(word[2]))
System.out.print("老师");
if (token.equalsIgnoreCase(word[3]))
System.out.print("学生");
} else {
System.out.println(token + "(不是该语言中的语句)");
}
}
}

Node的实现类ObjectPronounOrNounNode.java

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
package Interpreter;
public class ObjectPronounOrNounNode implements Node {
String[] word = {"Me", "Him", "Tiger", "Apple"};
String token;
boolean boo;
@Override
public void parse(Context context) {
token = context.nextToken();
int i = 0;
for (; i < word.length; i++) {
if (token.equalsIgnoreCase(word[i])) {
boo = true;
break;
}
}
if (i == word.length) {
boo = false;
}
}
@Override
public void execute() {
if (boo) {
if (token.equalsIgnoreCase(word[0]))
System.out.print("我");
if (token.equalsIgnoreCase(word[1]))
System.out.print("他");
if (token.equalsIgnoreCase(word[2]))
System.out.print("老虎");
if (token.equalsIgnoreCase(word[3]))
System.out.print("苹果");
} else {
System.out.println(token + "(不是该语言中的语句)");
}
}
}

Node的实现类VerbNode.java

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
package Interpreter;
public class VerbNode implements Node {
String[] word = {"Drink", "Eat", "Look", "beat"};
String token;
boolean boo;
@Override
public void parse(Context context) {
token = context.nextToken();
int i = 0;
for (; i < word.length; i++) {
if (token.equalsIgnoreCase(word[i])) {
boo = true;
break;
}
}
if (i == word.length) {
boo = false;
}
}
@Override
public void execute() {
if (boo) {
if (token.equalsIgnoreCase(word[0]))
System.out.print("喝");
if (token.equalsIgnoreCase(word[1]))
System.out.print("吃");
if (token.equalsIgnoreCase(word[2]))
System.out.print("看");
if (token.equalsIgnoreCase(word[3]))
System.out.print("打");
} else {
System.out.println(token + "(不是该语言中的语句)");
}
}
}

Node的实现类SubjectNode.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package Interpreter;
public class SubjectNode implements Node {
Node node;
@Override
public void parse(Context text) {
node = new SubjectPronounOrNounNode();
node.parse(text);
}
@Override
public void execute() {
node.execute();
}
}

Node的实现类PredicateNode.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
papackage Interpreter;
public class PredicateNode implements Node {
Node verbNode, objectNode;
@Override
public void parse(Context text) {
verbNode = new VerbNode();
objectNode = new ObjectPronounOrNounNode();
verbNode.parse(text);
objectNode.parse(text);
}
@Override
public void execute() {
verbNode.execute();
objectNode.execute();
}
}

Node的实现类SentenceNode.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package Interpreter;
public class SentenceNode implements Node {
Node subjectNode, predicateNode;
@Override
public void parse(Context text) {
subjectNode = new SubjectNode();
predicateNode = new PredicateNode();
subjectNode.parse(text);
predicateNode.parse(text);
}
@Override
public void execute() {
subjectNode.execute();
predicateNode.execute();
}
}

测试类Application.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package Interpreter;
public class Application {
public static void main(String[] args) {
String text = "Teacher beat tiger";
Context context = new Context(text);
Node node = new SentenceNode();
node.parse(context);
node.execute();
System.out.println();
text = "You eat apple";
context.setContext(text);
node.parse(context);
node.execute();
}
}

运行结果

老师打老虎
你吃苹果

解释器模式的优点

  • 将每一个语法规则表示成一个类,方便于实现简单的语言。
  • 由于使用类表示语法规则,可以较容易改变或扩展语言的行为。
  • 通过在类结构中加入新的方法,可以在解释的同时增加新的行为。

适用解释器模式的情景

  • 当有一个简单的语言需要解释执行,并且可以将该语言的每一个规则表示为一个类时,就可以使用解释模式。
注意:如果文法过于复杂,那么过多的文法规则使我们很艰难维护所给出的类。

下载源码请到

MyGitHub

文章目录
  1. 1. 解释器模式
  2. 2. Interpreter Pattern
  3. 3. 类图
  4. 4. 模式的结构与使用
  5. 5. 简单的例子
    1. 5.1. Node的接口类Dog.java
    2. 5.2. Context的类Context.java
    3. 5.3. Node的实现类SubjectPronounOrNounNode.java
    4. 5.4. Node的实现类ObjectPronounOrNounNode.java
    5. 5.5. Node的实现类VerbNode.java
    6. 5.6. Node的实现类SubjectNode.java
    7. 5.7. Node的实现类PredicateNode.java
    8. 5.8. Node的实现类SentenceNode.java
    9. 5.9. 测试类Application.java
  6. 6. 运行结果
  7. 7. 解释器模式的优点
  8. 8. 适用解释器模式的情景
  9. 9. 下载源码请到