解释器模式属于行为型模式
是按照一定的语义进行解释的方案,在日常编码中使用较少
在java中expression4J spring的SpEL表达式
用解释器模式实现对一个简单的加减法计算的解析
- Context 解释器上下文
- Expression 解释器接口
- 非终结符表达式: 通常由其它表达式组成;
- 终结符表达式: 一般为取值表达式,为递归树的叶子节点
/**
* 上下文
*
* @author cans
* @date 2022/5/14
**/
public class Context {
private final Map<String, Integer> params = new HashMap<>();
public void put(String key, int value) {
params.put(key, value);
}
public int getParam(String key) {
return this.params.get(key);
}
}
/**
* 非终结表达式
*
* @author cans
* @date 2022/5/14
**/
public class AddExpression implements Expression {
private final Expression left;
private final Expression right;
public AddExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) + right.interpret(context);
}
}
/**
* 非终结表达式 减法
*
* @author cans
* @date 2022/5/14
**/
public class SubExpression implements Expression {
private final Expression left;
private final Expression right;
public SubExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) - right.interpret(context);
}
}
/**
* 终结符表达式
*
* @author cans
* @date 2022/5/14
**/
public class ValueExpression implements Expression {
private final String key;
public ValueExpression(String key) {
this.key = key;
}
@Override
public int interpret(Context context) {
return context.getParam(key);
}
}
/**
* demo
*
* @author cans
* @date 2022/5/14
**/
public class ExpressionDemo {
@Test
public void demoTest() {
String ex = "a+b-c";
Context context = new Context();
context.put("a", 1);
context.put("b", 9);
context.put("c", 3);
Expression expression = this.parse(ex.toCharArray());
int interpret = expression.interpret(context);
System.out.println(ex + " = " + interpret);
}
private Expression parse(char[] arr) {
String one = String.valueOf(arr[0]);
ValueExpression left = new ValueExpression(one);
if (arr.length == 1) {
return left;
}
String op = String.valueOf(arr[1]);
Expression nextExp = this.parse(getNextChar(arr));
if (op.equals("+")) {
return new AddExpression(left, nextExp);
} else if (op.equals("-")) {
return new SubExpression(left, nextExp);
}
return null;
}
private char[] getNextChar(char[] arr) {
char[] newArr = new char[arr.length - 2];
System.arraycopy(arr, 2, newArr, 0, arr.length - 2);
return newArr;
}
}
输出结果: a+b-c = 7
优势:
- 扩展性极强也是最大的优势了
劣势:
- 类膨胀: 每个语法都需要一个实现类去对应解析,通常使用表达式都会比较复杂所以会产生很多实现类,为后期维护带来麻烦;
- 实现使用了递归: 递归会造成调试异常复杂,不利于维护;
- 效率问题: 循环和递归造成效率低下;
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)