一、解释器模式的概念
解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
解释器模式需要解决的是,如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。
Context[上下文类]:包含解释器之外的一些全局信息
AbstractExpression[抽象表达式]:声明一个抽象的解释操作,该接口为抽象语法树中所有的节点共享
TerminalExpression[终结符表达式]:实现与文法中的终结符相关的解释操作,实现抽象表达式中所要求的方法,文法中每一个终结符都有一个具体的终结表达式与之相对应
NonterminalExpression[非终结符表达式]:为文法中的非终结符相关的解释操作
二、解释器模式的实现
public class Context {
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String text;
}
public abstract class Expression {
public void interpret(Context context){
if(context.text.length()==0)
return;
else{
String key = context.text.substring(0,1);
double value = 0;
context.setText(context.text.substring(2));
int index = context.text.indexOf(" ");
if(index==-1) {
value = Double.parseDouble(context.text.substring(0, 1));
context.setText("");
}
else{
value = Double.parseDouble(context.text.substring(0, index));
context.setText(context.text.substring(index + 1));
}
execute(key,value);
}
}
public abstract void execute(String key,double value);
}
public class NoteExpression extends Expression {
@Override
public void execute(String key, double value) {
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;
}
System.out.println(note);
}
}
public class ScaleExpression extends Expression {
@Override
public void execute(String key, double value) {
String scale = "";
switch((int)value){
case 1:
scale = "low";
break;
case 2:
scale = "mid";
break;
case 3:
scale = "high";
break;
}
System.out.println(scale);
}
}
public class SpeedExpression extends Expression {
@Override
public void execute(String key, double value) {
String speed = "";
if(value==1)
speed = "慢速";
if(value==2)
speed = "中速";
if(value==3)
speed = "快速";
System.out.println(speed);
}
}
public class Client{
public static void main(String[] args) {
Context context = new Context();
context.setText("T 1 O 2 C 2 D 1 A 1");
Expression expression = null;
while (context.text.length()>0){
String str = context.text.substring(0,1);
switch (str){
case "O":
expression = new ScaleExpression();
break;
case "T":
expression = new SpeedExpression();
break;
default:
expression = new NoteExpression();
}
expression.interpret(context);
}
}
}
三、解释器模式的应用
浏览器解析HTML、正则表达式
一些重复发生的问题,比如加减乘除四则运算,但是公式每次都不同,有时是a+b-c*d,有时是a*b+c-d等等,公式千变万化,但是都是由加减乘除四个非终结符来连接的,这时我们就可以使用解释器模式
四、解释器の其他问题
可扩展性比较好,灵活;扩展语法增加新的解释表达式的方式;易于实现文法
执行效率比较低,可利用场景比少;语法复杂类膨胀;l对于复杂的文法比较难维护
五、Reference
六、Resource