随笔分类
解释器模式
Interpreter 模式
行为型模式之一
一种特殊的设计模式,建立一个解释器,对于特定的计算机程序设计语言,用来解释预先定义的文法
简单来说,Interpreter模式是一种简单的语法解释器架构
- Context:解释器上下文环境类。用来存储解释器上下文环境,比如需要解释的文法等
- AbstractExpression:解释器抽象类,解释器需要获取上下文环境后才能进行一系列的动作
- ConcreteExpression:解释器具体实现类
/**
* 上下文解释器
* 存储文法
* input 和 output 要同时进行更改
*/
public class Context {
public Context(String input) {
this.input = input;
}
private String input;
private int output;
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
public int getOutput() {
return output;
}
public void setOutput(int output) {
this.output = output;
}
}
/**
* 解释器接口
*/
public interface Expression {
void interpret(Context context);
}
/**
* 自动递增的解释器
*/
public class AutoIncreaseExpression implements Expression{
@Override
public void interpret(Context context) {
//提示信息
System.out.println("自动递增");
//获取上下文环境
String input = context.getInput();
int parseInt = Integer.parseInt(input);
//进行递增
++parseInt;
//保持最新状态
context.setInput(String.valueOf(parseInt));
context.setOutput(parseInt);
}
}
/**
* 自动递减的解释器
*/
public class AutoDecreaseExpression implements Expression{
@Override
public void interpret(Context context) {
//提示信息
System.out.println("自动递减");
//获取上下文环境
String input = context.getInput();
int parseInt = Integer.parseInt(input);
//进行递增
--parseInt;
//保持最新状态
context.setInput(String.valueOf(parseInt));
context.setOutput(parseInt);
}
}
/**
* 运行结果
* 自动递增
* 11
* 自动递增
* 12
* 自动递减
* 11
* 自动递减
* 10
* 自动递增
* 11
*/
public class Client {
public static void main(String[] args) {
Context context = new Context("10");
List<Expression> list = new ArrayList<>();
list.add(new AutoIncreaseExpression());
list.add(new AutoIncreaseExpression());
list.add(new AutoDecreaseExpression());
list.add(new AutoDecreaseExpression());
list.add(new AutoIncreaseExpression());
list.forEach(s -> {
s.interpret(context);
System.out.println(context.getOutput());
});
}
}
应用场景
- 当一个语言需要解释执行,并且你可以将该语言中的句子表示为一个抽象语法树时,可以使用解释器模式。存在以下情况情况时该模式效果最好
- 文法简单但对于复杂的文法,文法的类层次变得庞大而无法管理。此时文法分析程序生成器无疑是更好的选择。他们无需构建抽象语法树即可解释表达式,这样可以节省空间和时间
- 效率不是一个关键问题,最高效的解释器通常不是直接解释语法分析树实现的,而是首先将它们转换成另一种形式。
- 例如,正则表达式通常被转换成一个状态机,但即使在这种情况下,转换器仍可用解释器迷失实现,该模式仍是有用的
- 优点
- 可扩展性好
- 缺点
- 解释器模式采用递归调用方法,将会导致调试非常复杂
- 使用了大量的循环和递归,效率是一个不容忽视的问题
- 方法
- 构建语法树,定义终结符和非终结符
- 应用实例
- 编译器
- 运算表达式计算、正则表达式