当前位置: 首页 > news >正文

Java设计模式之解释器模式

概念

解释器模式是一种行为型设计模式,用于定义一种语言的语法规则,并提供解释器来解释该语言中的表达式。

作用

其核心作用是将复杂的语法分解为简单的语法单元,通过递归组合的方式构建抽象语法树(AST),最终由解释器逐层解释执行。

场景

1.需要解释特定领域的语言:如数学公式、正则表达式、SQL查询等。

2.语法相对简单且稳定:若语法频繁变化或过于复杂,建议使用解析器生成工具(如ANTLR)。

3.需要灵活扩展语法规则:通过新增解释器类即可支持新语法。

示例

以关系表达式计算为例——假设需要计算形如 A + B > C 的表达式,其中字母对应数值为所在字母表的位置(如 A=1,B=2)。以下是解释器模式的实现:

1.定义上下文类(保存变量值)

class Context {
    private Map<String, Integer> variables = new HashMap<>();

    public void setValue(String variable, int value) {
        variables.put(variable, value);
    }

    public int getValue(String variable) {
        return variables.get(variable);
    }
}

2. 定义数值表达式接口与实现

interface NumericExpression {
    int evaluate(Context context);
}
// 变量表达式(终结符)
class Variable implements NumericExpression {
    private String name;
    public Variable(String name) { this.name = name; }

    @Override
    public int evaluate(Context context) {
        return context.getValue(name);
    }
}
// 加法表达式(非终结符)
class Add implements NumericExpression {
    private NumericExpression left, right;
    public Add(NumericExpression l, NumericExpression r) {
        this.left = l;
        this.right = r;
    }

    @Override
    public int evaluate(Context context) {
        return left.evaluate(context) + right.evaluate(context);
    }
}

3. 定义布尔表达式接口与比较操作

// 布尔表达式接口
interface BooleanExpression {
    boolean evaluate(Context context);
}
// 大于比较
class GreaterThan implements BooleanExpression {
    private NumericExpression left, right;
    public GreaterThan(NumericExpression l, NumericExpression r) {
        this.left = l;
        this.right = r;
    }

    @Override
    public boolean evaluate(Context context) {
        return left.evaluate(context) > right.evaluate(context);
    }
}
// 等于比较
class Equal implements BooleanExpression {
    private NumericExpression left, right;
    public Equal(NumericExpression l, NumericExpression r) {
        this.left = l;
        this.right = r;
    }

    @Override
    public boolean evaluate(Context context) {
        return left.evaluate(context) == right.evaluate(context);
    }
}

4.测试类

public class InterpreterPatternDemo {
    public static void main(String[] args) {
        Context context = new Context();
        context.setValue("A", 1);
        context.setValue("B", 2);
        context.setValue("C", 3);
        context.setValue("D", 4);

        // 表达式:A + B = C → 1 + 2 = 3
        BooleanExpression expr1 = new Equal(
            new Add(new Variable("A"), new Variable("B")),
            new Variable("C")
        );
        System.out.println(expr1.evaluate(context)); // true

        // 表达式:B < C → 2 < 3
        BooleanExpression expr2 = new GreaterThan(
            new Variable("C"), new Variable("B")
        );
        System.out.println(expr2.evaluate(context)); // true

        // 表达式:A + B > D → 3 > 4
        BooleanExpression expr3 = new GreaterThan(
            new Add(new Variable("A"), new Variable("B")),
            new Variable("D")
        );
        System.out.println(expr3.evaluate(context)); // false
    }
}

优缺点

优点

缺点

易于扩展语法规则,新增表达式只需添加类。

类数量膨胀,复杂语法会导致难以维护。

将语法解析与具体操作分离,符合单一职责原则。

效率较低,递归解释过程可能影响性能。

不使用解释器模式的实现方式

若无需灵活扩展语法,可通过硬编码解析表达式字符串实现:

class SimpleEvaluator {
    public static boolean evaluate(String expr, Context context) {
        // 解析表达式(示例仅支持单一比较符)
        String[] parts = expr.split(">|<|==");
        if (parts.length != 2) throw new IllegalArgumentException();

        int leftVal = parseArithmetic(parts[0].trim(), context);
        int rightVal = parseArithmetic(parts[1].trim(), context);

        if (expr.contains(">")) return leftVal > rightVal;
        else if (expr.contains("<")) return leftVal < rightVal;
        else if (expr.contains("==")) return leftVal == rightVal;
        else throw new IllegalArgumentException();
    }

    private static int parseArithmetic(String expr, Context context) {
        if (expr.contains("+")) {
            String[] vars = expr.split("\\+");
            return context.getValue(vars[0].trim()) + context.getValue(vars[1].trim());
        }
        return context.getValue(expr.trim());
    }
}

// 使用示例
boolean result = SimpleEvaluator.evaluate("A + B == C", context);

缺点

1.代码耦合度高,新增语法需修改核心逻辑。

2.难以处理嵌套表达式(如 (A + B) * C > D)。

3.维护困难,容易引入错误。

相关文章:

  • ofd转pdf报错:org.ofdrw.reader.ZipUtil.unZipFileByApacheCommonCompress【已解决】
  • web爬虫笔记:js逆向案例十一 某数cookie(补环境流程)
  • C#委托介绍
  • 算法数论.3(拓展欧几里得,中国剩余定理)
  • 搭建第一个Spring项目
  • 题解:AT_abc170_f [ABC170F] Pond Skater
  • Linux中执行 ifconfig 命令时提示 “未找到命令”
  • 无人设备遥控器之调度自动化技术篇
  • MCP(大模型上下文协议)
  • C++ 的基本内置类型(十二)
  • springboot body 转对象强验证属性多余属性抛错误
  • [NO-WX179]基于springboot+微信小程序的在线选课系统
  • msvcp140.dll是什么文件?修复丢失msvcp140.dll的方法指南
  • Python FastAPI 面试题及参考答案
  • [CLS] Token 在 ViT(Vision Transformer)中的作用与实现
  • 模拟算法专题
  • 机器学习实战,涉及数据预处理、监督算法、无监督算法、模型评估与改进-思维导图
  • 【2025年第三期】全国数字人才技能提升师资培训班邀请函
  • LangChain其它五类组件详解(6)—— 查询分析(Query analysis)
  • uni-app常用模板
  • 上海婚登人聂晶:见证爱情故事开启,也向长久婚姻致敬
  • 视频丨习近平在河南洛阳市考察调研
  • 欧阳娜娜等20多名艺人被台当局列入重要查核对象,国台办回应
  • 专访|金七猫奖得主:以非遗为舟,在现实题材中疗愈与成长
  • 外媒:哈马斯一名高级指挥官尸体被发现,系辛瓦尔弟弟
  • 大外交丨3天拿下数万亿美元投资,特朗普在中东做经济“加法”和政治“减法”