解释器模式:给定的一个表达式,通过定义它的语法和一个解释器,来解释该表达式
我大概的理解是,类似于语法解析、表达式解析这种问题,我们通过分析它的表达式或者文本,通过定义出一套语法,然后根据这套语法实现一个解释器,通过这种方式来达到解析文本的目的。
其中使用的角色有三种:抽象表达式,具体表达式,环境
就用计算器为例子,为了说明问题,我们只解释不带括号的加减法表达式
首先定义一个抽象的表达式
public abstract class Expression {
public abstract int interpret(Context context); // Context是环境角色,在具体的表达式实例对象中会用到
}
具体 表达式:在这个示例中有三种表达式:变量,加法表达式,减法表达式
public class Variable extends Expression{
private String name;
public Variable(String name) {
this.name = name;
}
@Override
public int interpret(Context context) {
return context.getVariable(this);
}
@Override
public String toString() {
return name;
}
}
public class PlusExpression extends Expression{
private Expression left;
private Expression right;
public PlusExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) + right.interpret(context);
}
@Override
public String toString() {
return left.toString() + " + " + right.toString();
}
}
public class MinusExpression extends Expression{
private Expression left;
private Expression right;
public MinusExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) - right.interpret(context);
}
@Override
public String toString() {
return left.toString() + " - " + right.toString();
}
}
环境角色:
public class Context {
private Map<Variable, Integer> variableMap = new HashMap<>();
public void addVariable(Variable var, Integer value){
variableMap.put(var, value);
}
public int getVariable(Variable var){
return variableMap.get(var);
}
}
测试:
public class Client {
public static void main(String[] args) {
Context context = new Context();
Variable a = new Variable("a");
Variable b = new Variable("b");
Variable c = new Variable("c");
Variable d = new Variable("d");
context.addVariable(a, 5);
context.addVariable(b, 2);
context.addVariable(c, 6);
context.addVariable(d, 3);
// 构建表达式:a - b + c - d
Expression expressionA = new MinusExpression(new PlusExpression(new MinusExpression(a, b), c), d);
int resultA = expressionA.interpret(context);
System.out.println(expressionA.toString() + " = " + resultA);
// a + b - c + d
Expression expressionB = new PlusExpression(new MinusExpression(new PlusExpression(a, b) ,c) , d);
int resultB = expressionB.interpret(context);
System.out.println(expressionB.toString() + " = " + resultB);
}
}
解释器模式的使用比较受限。其中构建表达式和求解的部分中,用到的其实递归的思想,把一个大问题拆解成一个一个的小问题,小问题解决了,大问题自然就解决了。但是使用递归是一件比较复杂的事,对于程序来说开销比较大,如果表达式比较复杂,那么要定义的具体表达式就会很多。