解释器模式结构图:
示例代码:
// 抽象表达式角色
public interface ArithmeticInterpreter {
int interpret();
}
// 终结表达式角色
public abstract class Interpreter implements ArithmeticInterpreter{
protected ArithmeticInterpreter left;
protected ArithmeticInterpreter right;
public Interpreter(ArithmeticInterpreter left, ArithmeticInterpreter right) {
this.left = left;
this.right = right;
}
}
// 加法解释器
public class AddInterpreter extends Interpreter{
public AddInterpreter(ArithmeticInterpreter left, ArithmeticInterpreter right) {
super(left, right);
}
@Override
public int interpret() {
return this.left.interpret() + this.right.interpret();
}
}
// 减法解释器
public class SubInterpreter extends Interpreter{
public SubInterpreter(ArithmeticInterpreter left, ArithmeticInterpreter right) {
super(left, right);
}
@Override
public int interpret() {
return this.left.interpret() - this.right.interpret();
}
}
// 乘法解释器
public class MultiInterpreter extends Interpreter{
public MultiInterpreter(ArithmeticInterpreter left, ArithmeticInterpreter right) {
super(left, right);
}
@Override
public int interpret() {
return this.left.interpret() * this.right.interpret();
}
}
// 除法解释器
public class DivInterpreter extends Interpreter{
public DivInterpreter(ArithmeticInterpreter left, ArithmeticInterpreter right) {
super(left, right);
}
@Override
public int interpret() {
return this.left.interpret() / this.right.interpret();
}
}
// 数字表达式类
public class NumInterpreter implements ArithmeticInterpreter{
private int value;
public NumInterpreter(int value) {
this.value = value;
}
@Override
public int interpret() {
return value;
}
}
// 计算器,没有考虑优先级,就是简单的从左到右的计算
public class GPCalculator {
private Stack<ArithmeticInterpreter> stack = new Stack<>();
public GPCalculator(String expression){
this.parse(expression);
}
private void parse(String expression) {
String[] elements = expression.split(" ");
ArithmeticInterpreter left;
ArithmeticInterpreter right;
for (int i = 0; i < elements.length; i++) {
String operator = elements[i];
if (OperatorUtil.ifOperator(operator)){
left = this.stack.pop();
right = new NumInterpreter(Integer.valueOf(elements[++i]));
System.out.println("出栈" + left.interpret() + "和" + right.interpret());
this.stack.push(OperatorUtil.getInterpreter(left,right,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 ifOperator(String operator) {
return (operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/"));
}
public static ArithmeticInterpreter getInterpreter(ArithmeticInterpreter left, ArithmeticInterpreter right, String operator) {
if (operator.equals("+")){
return new AddInterpreter(left,right);
}else if (operator.equals("-")){
return new SubInterpreter(left, right);
}else if (operator.equals("*")){
return new MultiInterpreter(left, right);
}else if (operator.equals("/")){
return new DivInterpreter(left, right);
}
return null;
}
}
// 测试类
public class InterpreterTest {
public static void main(String[] args) {
System.out.println("result: " + new GPCalculator("10 + 30").calculate());
System.out.println("result: " + new GPCalculator("10 + 30 - 20").calculate());
System.out.println("result: " + new GPCalculator("100 * 2 + 30").calculate());
}
}
总结:
优点:解偶,增加了新的解释表达式的方式;
缺点:每个语法都要产生一个非终结符表达式,增加了系统的维护难度,解释器采用递归调用的方法,当完整表达式层级较深时,解释效率下降,且出错时调试困难.
原文:https://www.cnblogs.com/wqlken/p/14716389.html