浅谈Java设计模式——解释器模式(Interpreter)
一、概述
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。解释器模式描述了如何构成一个简单的语言解释器,主要应用在使用面向对象语言开发的编译器中。它描述了如何为简单的语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这些句子。
二、使用场景
当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使 用解释器模式。而当存在以下情况时该模式效果最好:
1.该文法简单对于复杂的文法,文法的类层次变得庞大而无法管理。
2.效率不是一个关键问题最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先将它们转换成另一种形式。
三、参与者
1.AbstractExpression(抽象表达式) 声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。
2.TerminalExpression(终结符表达式) 实现与文法中的终结符相关联的解释操作。 一个句子中的每个终结符需要该类的一个实例。
3.NonterminalExpression(非终结符表达式) 为文法中的非终结符实现解释(Interpret)操作。
4.Context(上下文) 包含解释器之外的一些全局信息。
5.Client(客户) 构建(或被给定)表示该文法定义的语言中一个特定的句子的抽象语法树。 该抽象语法树由NonterminalExpression和TerminalExpression的实例装配而成。 调用解释操作。
四、类图
五、代码示例
1.AbstractExpression(抽象表达式)
/**
* AbstractExpression:
* 表达式类:Expression
* @author zhipeng_Tong
*/
public abstract class Expression { // 表达式
// 解释器
public void interpreter(PlayContext context) throws Exception {
if (context.getText().length() == 0)
return;
else {
String playKey = context.getText().substring(0, 1);
context.setText(context.getText().substring(2));
double playValue = Double.parseDouble(context.getText().
substring(0, context.getText().indexOf(" ")));
context.setText(context.getText().substring(context.getText().indexOf(" ") + 1));
excute(playKey, playValue);
}
}
// 执行
public abstract void excute(String key, double value) throws Exception;
}
2.TerminalExpression(终结符表达式)
/**
* TerminalExpression
*
* @author zhipeng_Tong
*/
public class Note extends Expression { // 音韵
@Override
public void excute(String key, double value) throws Exception {
String note = "";
switch (key) {
case "C":
note = "1";
break;
case "D":
note = "2";
break;
case "E":
note = "3";
break;
case "F":
note = "4";
break;
case "G":
note = "5";
break;
case "A":
note = "6";
break;
case "B":
note = "7";
break;
default:
throw new Exception("输入有误!");
}
System.out.print(note + " ");
}
}
/**
* TerminalExpression
*
* @author zhipeng_Tong
*/
public class Scale extends Expression { // 音阶
@Override
public void excute(String key, double value) throws Exception {
String scale = "";
switch ((int)value) {
case 1:
scale = "低音";
break;
case 2:
scale = "中音";
break;
case 3:
scale = "高音";
break;
default:
throw new Exception("输入有误!");
}
System.out.print(scale + " ");
}
}
3.NonterminalExpression(非终结符表达式) 为文法中的非终结符实现解释(Interpret)操作。
4.Context(上下文)
/**
* Context
*
* @author zhipeng_Tong
*/
public class PlayContext { // 演奏者
// 演奏的文本
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
5.Client(客户) 构建(或被给定)表示该文法定义的语言中一个特定的句子的抽象语法树。 该抽象语法树由NonterminalExpression和TerminalExpression的实例装配而成。 调用解释操作。
public class Client {
public static void main(String[] args) {
PlayContext context = new PlayContext();
System.out.println("上海滩:");
context.setText("O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3 ");
Expression expression = null;
try {
while (context.getText().length() > 0) {
String str = context.getText().substring(0, 1);
if (str == " ")
continue;
switch (str) {
case "O":
expression = new Scale();
break;
case "C":
case "D":
case "E":
case "F":
case "G":
case "A":
case "B":
case "P":
expression = new Note();
break;
}
expression.interpreter(context);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果
上海滩:
中音 3 5 6 3 5 2 3 5 6 高音 1 中音 6 5 1 3 2