1、概述
行为型模式
解释器模式(Interpreter Pattern)指给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子,属于行为型设计模式。
主要角色
抽象表达式(IExpression):负责定义一个解释方法 interpret,交由具体子类进行具体解释。
终结符表达式(TerminalExpression):实现文法中与终结符有关的解释操作。通常一个解释器中只有- 一个终结符表达式,但有多个实例,对应不同的终结符。
非终结符表达式(NonterminalExpression):实现文法中与非终结符有关的解释操作。
上下文环境类(Context):包含解释器之外的全局信息。它一般用来存放文法中各个终结符所对应的具体值。
2、优缺点
优点
可以通过继承等方式改变和扩展文法。每一个文法都可以表示为一个类,可以方便的实现一个语言。方便的增加新的解释表达式。
缺点
对于复杂的文法可能需要定义过多的解释类,难以维护。执行效率下,解释器模式中使用了大量的循环和递归调用,对于复杂的文法执行效率低。
文法比较简单。执行效率不是关键。一些重复出现的问题可以用一种简单的语言来表达。可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
3、实现方式
import java.util.Stack;
//测试类
public class Test {
public static void main(String[] args) {
GPCalculator gpCalculator = new GPCalculator("2 + 3");
System.out.println("2 + 3 = "+ gpCalculator.calculate());
System.out.println("-------------");
GPCalculator gpCalculator2 = new GPCalculator("2 * 3");
System.out.println("2 * 3 = "+ gpCalculator2.calculate());
System.out.println("-------------");
GPCalculator gpCalculator3 = new GPCalculator("2 + 3 - 1");
System.out.println("2 + 3 - 1 = "+ gpCalculator3.calculate());
}
}
interface IArithmeticInterpreter {
int interpret();
}
// 数字表达式
class NumberInterpreter implements IArithmeticInterpreter {
private int value;
public NumberInterpreter(int value) {
this.value = value;
}
@Override
public int interpret() {
return this.value;
}
}
abstract class Interpreter implements IArithmeticInterpreter {
protected IArithmeticInterpreter left;
protected IArithmeticInterpreter right;
public Interpreter(IArithmeticInterpreter left, IArithmeticInterpreter right) {
this.left = left;
this.right = right;
}
}
class AddInterpreter extends Interpreter {
public AddInterpreter(IArithmeticInterpreter left, IArithmeticInterpreter right) {
super(left, right);
}
@Override
public int interpret() {
return this.left.interpret() + this.right.interpret();
}
}
class SubInterpreter extends Interpreter {
public SubInterpreter(IArithmeticInterpreter left, IArithmeticInterpreter right) {
super(left, right);
}
@Override
public int interpret() {
return this.left.interpret() - this.right.interpret();
}
}
class MultiInterpreter extends Interpreter {
public MultiInterpreter(IArithmeticInterpreter left, IArithmeticInterpreter right) {
super(left, right);
}
@Override
public int interpret() {
return this.left.interpret() * this.right.interpret();
}
}
class DivInterpreter extends Interpreter {
public DivInterpreter(IArithmeticInterpreter left, IArithmeticInterpreter right) {
super(left, right);
}
@Override
public int interpret() {
return this.left.interpret() / this.right.interpret();
}
}
class GPCalculator {
private Stack<IArithmeticInterpreter> stack = new Stack<>();
public GPCalculator(String expression) {
this.parse(expression);
}
/**
* 解析表达式:约定表达式以空格分隔
*
* @param expression
*/
private void parse(String expression) {
String[] elements = expression.split(" ");
IArithmeticInterpreter left, right;
for (int i = 0; i < elements.length; i++) {
String operator = elements[i];
if("+".equals(operator) || "-".equals(operator) || "*".equals(operator) || "/".equals(operator)){
System.out.println("应用运算符:" + operator);
left = this.stack.pop();
right = new NumberInterpreter(Integer.valueOf(elements[++i]));
System.out.println("出栈:left=" + left.interpret() + ", right=" + right.interpret());
Interpreter interpreter = null;
if("+".equals(operator)){
interpreter = new AddInterpreter(left, right);
}else if("-".equals(operator)){
interpreter = new SubInterpreter(left, right);
}else if("*".equals(operator)){
interpreter = new MultiInterpreter(left, right);
}else if("/".equals(operator)){
interpreter = new DivInterpreter(left, right);
}else{
new RuntimeException("不支持该运算符:" + operator);
}
this.stack.push(interpreter);
System.out.println("应用运算符计算结果入栈,result=" + interpreter.interpret());
}else{
NumberInterpreter numberInterpreter = new NumberInterpreter(Integer.valueOf(elements[i]));
this.stack.push(numberInterpreter);
System.out.println("入栈:" + numberInterpreter.interpret());
}
}
}
// 获取计算结果
public int calculate() {
return this.stack.pop().interpret();
}
}
4、应用场景
1)一些重复出现的问题可以用一种简单的语言进行表达。
2)一个简单语法需要解释的场景。
3)逆波兰表达式