当有一个语言需要解释执行,可将该语言中的句子表示为一个抽象语法树,就可以考虑使用解释器模式,让程序具有良好的扩展性应用场景:编译器、运算表达式计算、正则表达式、机器人等使用解释器可能带来的问题:解释器模式会引起类膨胀、解释器模式采用递归调用方法,将会导致调试非常复杂、效率可能降低.
//解释器设计模式
public class InterpreterPattern {
public static void main (String[] args) throws IOException {
String expStr = getExpStr(); // a+b
HashMap<String, Integer> var = getValue(expStr);// var {a=10, b=20}
Calculator calculator = new Calculator(expStr);
System.out.println("运算结果:" + expStr + "=" + calculator.run(var));
}
// 获得表达式
public static String getExpStr() throws IOException {
System.out.print("请输入表达式:");
return (new BufferedReader(new InputStreamReader(System.in))).readLine();
}
// 获得值映射
public static HashMap<String, Integer> getValue(String expStr) throws IOException {
HashMap<String, Integer> map = new HashMap<>();
for (char ch : expStr.toCharArray()) {
if (ch != '+' && ch != '-') {
if (!map.containsKey(String.valueOf(ch))) {
System.out.print("请输入" + String.valueOf(ch) + "的值:");
String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
map.put(String.valueOf(ch), Integer.valueOf(in));
}
}
}
return map;
}
}
//抽象类表达式,可以获取到变量的值
abstract class Expression {
//HashMap {a=10,b=20}
abstract int interpreter(HashMap<String, Integer> var);
}
class VarExpression extends Expression {
private String key;
public VarExpression(String key) {
this.key = key;
}
@Override
int interpreter(HashMap<String, Integer> var) {
return var.get(this.key);
}
}
class SymbolExpression extends Expression {
protected Expression left;
protected Expression right;
public SymbolExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
//因为SymbolExpression是让其子类来实现的,interpreter是一个默认实现
@Override
int interpreter(HashMap<String, Integer> var) {
return 0;
}
}
class AddExpression extends SymbolExpression {
public AddExpression(Expression left, Expression right) {
super(left, right);
}
//返回left, right 表达式的值将其相加
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) + super.right.interpreter(var);
}
}
class SubExpression extends SymbolExpression {
public SubExpression(Expression left, Expression right) {
super(left, right);
}
//返回left, right 表达式的值将其相减
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) - super.right.interpreter(var);
}
}
class Calculator {
// 定义表达式
private Expression expression;
// 构造函数传参,并解析
public Calculator(String expStr) { // expStr = a+b
// 安排运算先后顺序
Stack<Expression> stack = new Stack<>();
// 表达式拆分成字符数组
char[] charArray = expStr.toCharArray();// [a, +, b]
Expression left = null; Expression right = null;
//遍历我们的字符数组, 即遍历 [a, +, b]
//针对不同的情况,做处理
for (int i = 0; i < charArray.length; i++) { switch (charArray[i]) {
case '+': //
left = stack.pop();// 从 stack 取 出 left => "a"
right = new VarExpression(String.valueOf(charArray[++i]));// 取出右表达式 "b"
stack.push(new AddExpression(left, right));// 然后根据得到 left 和 right 构建 AddExpresson 加入stack
break;
case '-': //
left = stack.pop();
right = new VarExpression(String.valueOf(charArray[++i]));
stack.push(new SubExpression(left, right));
break;
default:
//如果是一个 Var 就创建要给 VarExpression 对象,并 push 到 stack
stack.push(new VarExpression(String.valueOf(charArray[i])));
break;
}
}
//当遍历完整个 charArray 数组后,stack 就得到最后 Expression
this.expression = stack.pop();
}
public int run(HashMap<String, Integer> var) {
//最后将表达式 a+b 和 var = {a=10,b=20}
//然后传递给 expression 的 interpreter 进行解释执行
return this.expression.interpreter(var);
}
}