# 解释器模式(Interpreter Pattern)

目录: https://note.dolyw.com/design/ (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));
    }
}
上次更新时间: 2023-12-15 03:14:55