# 解释器模式(Interpreter Pattern)
代码地址
- Github:DesignPattern/src/main/java/com/design/interpreter (opens new window)
- Gitee(码云):DesignPattern/src/main/java/com/design/interpreter (opens new window)
# 1. 介绍
解释器模式提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等
# 1.1. 特点
待补充
# 1.2. 结构
待补充
# 1.3. 优缺点
- 意图:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子
- 主要解决:对于一些固定文法构建一个解释句子的解释器
- 何时使用:如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题
- 如何解决:构建语法树,定义终结符与非终结符
- 关键代码:构建环境类,包含解释器之外的一些全局信息,一般是 HashMap
- 应用实例:编译器、运算表达式计算
- 优点:
- 可扩展性比较好,灵活
- 增加了新的解释表达式的方式
- 易于实现简单文法
- 缺点:
- 可利用场景比较少
- 对于复杂的文法比较难维护
- 解释器模式会引起类膨胀
- 解释器模式采用递归调用方法
- 使用场景:
- 可以将一个需要解释执行的语言中的句子表示为一个抽象语法树
- 一些重复出现的问题可以用一种简单的语言来进行表达
- 一个简单语法需要解释的场景。
- 注意事项:可利用场景比较少,JAVA 中如果碰到可以用 Expression, expression4J 代替
# 2. 代码
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import java.util.ArrayList;
import java.util.List;
/**
* 解释器模式 - 可利用场景比较少
* 可以直接使用Spring及Java自带的
*
* @author wliduo[i@dolyw.com]
* @date 2023/2/2 16:22
*/
public class Main {
public static void main(String[] args) {
// 创建一个ExpressionParser对象,用于解析表达式
ExpressionParser parser = new SpelExpressionParser();
// 最简单的字符串表达式
Expression exp = parser.parseExpression("'HelloWorld'");
System.out.println("'HelloWorld'的结果:" + exp.getValue());
// 调用方法的表达式
exp = parser.parseExpression("'HelloWorld'.concat('!')");
System.out.println("'HelloWorld'.concat('!')的结果: " + exp.getValue());
// 调用对象的getter方法
exp = parser.parseExpression("'HelloWorld'.bytes");
System.out.println("'HelloWorld'.bytes的结果: " + exp.getValue());
// 访问对象的属性(相当于HelloWorld.getBytes().length)
exp = parser.parseExpression("'HelloWorld'.bytes.length");
System.out.println("'HelloWorld'.bytes.length的结果:" + exp.getValue());
// 使用构造器来创建对象
exp = parser.parseExpression("new String('helloworld')" + ".toUpperCase()");
System.out.println("new String('helloworld')" + ".toUpperCase()的结果是: " + exp.getValue(String.class));
// List解释
List<Boolean> list = new ArrayList<>();
list.add(true);
EvaluationContext ctx2 = new StandardEvaluationContext();
// 将list设置成EvaluationContext的一个变量
ctx2.setVariable("list", list);
// 修改list变量的第一个元素的值
parser.parseExpression("#list[0]").setValue(ctx2, "false");
// list集合的第一个元素被改变
System.out.println("list集合的第一个元素为:" + parser.parseExpression("#list[0]").getValue(ctx2));
}
}