解释器模式(Interpreter Pattern) 是指给定一门语言, 定义它的语法的一种表示, 并定义一个解释器,该解释器使用该表示来解释语言中的句子。是一种按照规定的语法进行解析的模式,属于行为型模式。
就比如编译器可以将源码编译解释为机器码, 让CPU能进行识别并运行。解释器模式的作用其实与编译器一样,都是将一些固定的语法进行解释,构建出一个解释句子的解释器。简单理解,解释器是一个简单语法分析工具,它可以识别句子语义,分离终结符号和非
终结符号,提取出需要的信息,让我们能针对不同的信息做出相应的处理。其核心思想是识别语法,构建解释。
其实我们每天都生活在解释器模式中,我们平时所听到的音乐都可以通过简谱记录下来;还有战争年代发明的摩尔斯电码(又译为摩斯密码, Morsecode) , 其实也是一种解释器。我们的程序中,如果存在一种特定类型的问题,该类型问题涉及多个不同实例,但是具备固定语法描述,那么可以使用解释器模式对该类型问题进行解释,分离出需要的信息,根据获取的信息做出相应的处理。简而言之,对于一些固定语法构建一个解释句子的解释器。解释器模式适用于以下应用场景:
下面我们用解释器模式来实现一个数学表达式计算器,包含加减乘除运算。首先定义抽象表达式角色IArithmeticInterpreter接口:
public interface IArithmeticInterpreter {
int interpret();
}
创建终结表达式角色AbstractInterpreter抽象类:
public abstract class AbstractInterpreter implements IArithmeticInterpreter {
protected IArithmeticInterpreter left;
protected IArithmeticInterpreter right;
public AbstractInterpreter(IArithmeticInterpreter left, IArithmeticInterpreter right) {
this.left = left;
this.right = right;
}
}
分别创建非终结表达式角色加、减、乘、除解释器:
//加
public class AddInterpreter extends AbstractInterpreter {
public AddInterpreter(IArithmeticInterpreter left, IArithmeticInterpreter right) {
super(left, right);
}
public int interpret() {
return this.left.interpret() + this.right.interpret();
}
}
//减
public class SubInterpreter extends AbstractInterpreter {
public SubInterpreter(IArithmeticInterpreter left, IArithmeticInterpreter right) {
super(left, right);
}
public int interpret() {
return this.left.interpret() - this.right.interpret();
}
}
//乘
public class MultiInterpreter extends AbstractInterpreter {
public MultiInterpreter(IArithmeticInterpreter left, IArithmeticInterpreter right){
super(left,right);
}
public int interpret() {
return this.left.interpret() * this.right.interpret();
}
}
//除
public class DivInterpreter extends AbstractInterpreter {
public DivInterpreter(IArithmeticInterpreter left, IArithmeticInterpreter right){
super(left,right);
}
public int interpret() {
return this.left.interpret() / this.right.interpret();
}
}
创建数字表达式类:
public class NumInterpreter implements IArithmeticInterpreter {
private int value;
public NumInterpreter(int value) {
this.value = value;
}
public int interpret() {
return this.value;
}
}
创建计算器类:不在乎乘除与加减得顺序,这都是解释器按照语义得解释,本案例中按照顺序执行
public class Calculator {
private Stack<IArithmeticInterpreter> stack = new Stack<IArithmeticInterpreter>();
public Calculator(String expression) {
this.parse(expression);
}
private void parse(String expression) {
String [] elements = expression.split(" ");
IArithmeticInterpreter leftExpr, rightExpr;
for (int i = 0; i < elements.length ; i++) {
String operator = elements[i];
if (OperatorUtil.isOperator(operator)){
leftExpr = this.stack.pop();
rightExpr = new NumInterpreter(Integer.valueOf(elements[++i]));
System.out.println("出栈: " + leftExpr.interpret() + " 和 " + rightExpr.interpret());
this.stack.push(OperatorUtil.getInterpreter(leftExpr, rightExpr,operator));
System.out.println("应用运算符: " + operator);
}
else{
NumInterpreter numInterpreter = new NumInterpreter(Integer.valueOf(elements[i]));
this.stack.push(numInterpreter);
System.out.println("入栈: " + numInterpreter.interpret());
}
}
}
public int calculate() {
return this.stack.pop().interpret();
}
}
操作工具类:
public class OperatorUtil {
public static boolean isOperator(String symbol) {
return (symbol.equals("+") || symbol.equals("-") || symbol.equals("*"));
}
public static AbstractInterpreter getInterpreter(IArithmeticInterpreter left, IArithmeticInterpreter right, String symbol) {
if (symbol.equals("+")) {
return new AddInterpreter(left, right);
} else if (symbol.equals("-")) {
return new SubInterpreter(left, right);
} else if (symbol.equals("*")) {
return new MultiInterpreter(left, right);
} else if (symbol.equals("/")) {
return new DivInterpreter(left, right);
}
return null;
}
}
测试类:
public class Test {
public static void main(String[] args) {
System.out.println("result: " + new Calculator("10 + 30").calculate());
System.out.println("result: " + new Calculator("10 + 30 - 20").calculate());
System.out.println("result: " + new Calculator("100 * 2 + 400 * 1 + 66").calculate());
}
}
优点:
缺点:
原文:https://www.cnblogs.com/wuzhenzhao/p/12564887.html