23 种设计模式中的解释器模式

给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

这种模式通常用于需要解释执行某种语言的场景,如正则表达式、SQL解析等。

解释器模式的核心组件。

  • 抽象表达式(AbstractExpression):声明一个抽象的解释操作
  • 终结符表达式(TerminalExpression):实现与文法中的终结符相关的解释操作
  • 非终结符表达式(NonterminalExpression):实现文法规则的解释操作
  • 上下文(Context):包含解释器之外的一些全局信息
  • 客户端(Client):构建表示该文法定义的语言中一个特定句子的抽象语法树

下面通过实现一个简单的数学表达式的解释器,来演示解释器模式。

抽象表达式接口。

java 复制代码
public interface Expression {
    int interpret();
}

终结符表达式实现。

java 复制代码
public class NumberExpression implements Expression {
    private int number;
    
    public NumberExpression(int number) {
        this.number = number;
    }
    
    @Override
    public int interpret() {
        return number;
    }
}

非终结符表达式(加法)。

java 复制代码
public class AddExpression implements Expression {
    private Expression left;
    private Expression right;
    
    public AddExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }
    
    @Override
    public int interpret() {
        return left.interpret() + right.interpret();
    }
}

非终结符表达式(减法)。

java 复制代码
public class SubtractExpression implements Expression {
    private Expression left;
    private Expression right;
    
    public SubtractExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }
    
    @Override
    public int interpret() {
        return left.interpret() - right.interpret();
    }
}

上下文类。

java 复制代码
import java.util.Stack;

public class ExpressionParser {
    public static Expression parse(String expression) {
        Stack<Expression> stack = new Stack<>();
        String[] tokens = expression.split(" ");
        
        for (int i = 0; i < tokens.length; i++) {
            String token = tokens[i];
            
            if (isOperator(token)) {
                Expression left = stack.pop();
                Expression right = new NumberExpression(Integer.parseInt(tokens[++i]));
                Expression operator = getOperatorExpression(token, left, right);
                stack.push(operator);
            } else {
                stack.push(new NumberExpression(Integer.parseInt(token)));
            }
        }
        
        return stack.pop();
    }
    
    private static boolean isOperator(String token) {
        return token.equals("+") || token.equals("-");
    }
    
    private static Expression getOperatorExpression(String operator, 
                                                  Expression left, 
                                                  Expression right) {
        switch (operator) {
            case "+": return new AddExpression(left, right);
            case "-": return new SubtractExpression(left, right);
            default: throw new IllegalArgumentException("Unknown operator: " + operator);
        }
    }
}

客户端,测试输出结果。

java 复制代码
public class InterpreterDemo {
    public static void main(String[] args) {
        String expression = "1 + 2 - 3 + 4";
        Expression parsedExpression = ExpressionParser.parse(expression);
        int result = parsedExpression.interpret();
        
        System.out.println(expression + " = " + result);
    }
}

解释器模式为特定类型的问题提供了优雅的解决方案,但在实际应用中需要权衡其复杂性和性能影响。

总结

解释器模式通过定义语法树来实现对用户输入内容的解释执行。

解释器模式在 Java 中可能不是首选,如果遇到适用场景,可以考虑使用外部依赖库来代替。

相关推荐
乐观的Terry6 分钟前
10、发布系统-路由管理与灰度发布
java
啦啦啦啦啦zzzz9 分钟前
设计模式:原型模式
c++·设计模式·原型模式
唐青枫14 分钟前
Java WebLogic 实战指南:从 Domain、数据源到 WAR 部署和集群管理
java
2501_937860941 小时前
Java 集合底层深度剖析:Map 与 Set、二叉搜索树、哈希表全解
java·数据结构·散列表
cyforkk1 小时前
并发控制与状态安全:Single-Flight 与幂等性的本质区别
java·安全·spring
董员外1 小时前
RAG 系统进化论(五):Corrective RAG 与 Self-RAG,让系统发现并纠正错误
人工智能·后端·设计模式
豆角焖肉1 小时前
MyBatis延迟加载、缓存机制与注解开发
java·spring·mybatis
所愿ღ2 小时前
SSM框架-Spring3
java·开发语言·笔记·spring
java1234_小锋2 小时前
【免费】基于Spark实时交通流量分析与拥堵预测系统(Java版本+可视化大屏+Kafka+SpringBoot+Vue3) 锋哥原创出品,必属精品
java·大数据·spark·kafka·实时交通流量分析与拥堵预测
组合缺一2 小时前
Solon 的 10 种 HTTP 服务器:改一行依赖,换一个引擎
java·服务器·网络协议·http·solon