Java设计模式之行为型模式(解释器模式)实现方式详解

解释器模式是一种行为型设计模式,用于定义一种语言的文法,并且构建一个解释器来解释该语言中的句子。这种模式常用于处理简单语言的语法解析。

下面是一个简单的例子,使用Java实现一个基本的四则运算表达式求值器(仅支持加减乘除和括号)。

示例场景:

我们希望创建一个简单的数学表达式求值器,它可以解析并计算像 "3 + 5 * (10 - 4)" 这样的字符串表达式。

解释器模式的核心组件包括:

  • 抽象表达式(Abstract Expression): 声明一个抽象的解释操作。
  • 终结符表达式(Terminal Expression): 实现与文法规则中终结符相关的解释操作。
  • 非终结符表达式(Nonterminal Expression): 为文法规则中的非终结符声明一个解释操作。
  • 上下文(Context): 包含解释器之外的一些全局信息。

下面是具体的代码实现:

java 复制代码
import java.util.Stack;
// 抽象表达式接口
interface Expression {
    int interpret();
}
// 终结符表达式:数字
class NumberExpression implements Expression {
    private final int number;
    public NumberExpression(int number) {
        this.number = number;
    }
    @Override
    public int interpret() {
        return number;
    }
}
// 非终结符表达式基类:二元操作符
abstract class BinaryOperation implements Expression {
    protected final Expression leftOperand;
    protected final Expression rightOperand;
    public BinaryOperation(Expression leftOperand, Expression rightOperand) {
        this.leftOperand = leftOperand;
        this.rightOperand = rightOperand;
    }
}
// 加法操作
class AddExpression extends BinaryOperation {
    public AddExpression(Expression leftOperand, Expression rightOperand) {
        super(leftOperand, rightOperand);
    }
    @Override
    public int interpret() {
        return leftOperand.interpret() + rightOperand.interpret();
    }
}
// 减法操作
class SubtractExpression extends BinaryOperation {
    public SubtractExpression(Expression leftOperand, Expression rightOperand) {
        super(leftOperand, rightOperand);
    }
    @Override
    public int interpret() {
        return leftOperand.interpret() - rightOperand.interpret();
    }
}
// 乘法操作
class MultiplyExpression extends BinaryOperation {
    public MultiplyExpression(Expression leftOperand, Expression rightOperand) {
        super(leftOperand, rightOperand);
    }
    @Override
    public int interpret() {
        return leftOperand.interpret() * rightOperand.interpret();
    }
}
// 除法操作
class DivideExpression extends BinaryOperation {
    public DivideExpression(Expression leftOperand, Expression rightOperand) {
        super(leftOperand, rightOperand);
    }
    @Override
    public int interpret() {
        if (rightOperand.interpret() == 0) {
            throw new ArithmeticException("Cannot divide by zero");
        }
        return leftOperand.interpret() / rightOperand.interpret();
    }
}
public class InterpreterPatternDemo {
    // 表达式的解析方法
    public static Expression parse(String expression) {
        Stack stack = new Stack<>();
        String[] tokens = expression.split("\\s+");
        for (String token : tokens) {
            switch (token) {
                case "+":
                    Expression addRight = stack.pop();
                    Expression addLeft = stack.pop();
                    stack.push(new AddExpression(addLeft, addRight));
                    break;
                case "-":
                    Expression subRight = stack.pop();
                    Expression subLeft = stack.pop();
                    stack.push(new SubtractExpression(subLeft, subRight));
                    break;
                case "*":
                    Expression mulRight = stack.pop();
                    Expression mulLeft = stack.pop();
                    stack.push(new MultiplyExpression(mulLeft, mulRight));
                    break;
                case "/":
                    Expression divRight = stack.pop();
                    Expression divLeft = stack.pop();
                    stack.push(new DivideExpression(divLeft, divRight));
                    break;
                default:
                    stack.push(new NumberExpression(Integer.parseInt(token)));
                    break;
            }
        }
        return stack.pop();
    }
    public static void main(String[] args) {
        String expression = "3 + 5 * (10 - 4)";
        Expression parsedExpression = parse(expression.replaceAll("\\(", "").replaceAll("\\)", ""));
        System.out.println("Parsed expression: " + expression);
        System.out.println("Result: " + parsedExpression.interpret());
    }
}

说明:

在这个例子中,我们实现了四种基本的操作:加、减、乘、除。每个操作都被表示为一个实现了 Expression 接口的具体类。通过栈的数据结构,我们可以方便地对表达式进行解析和计算。

相关推荐
牧瀬クリスだ4 分钟前
YAML配置详解:SpringBoot实战指南
java·spring·yml
Su5736 分钟前
RuoYi + RAGFlow 搭建私有化知识库完整集成实践(二)
java
wechatbot88812 分钟前
极客互动企业微信 SCRM 自动运营平台效果实测
java·微信·企业微信·rpa
需要82616 分钟前
JVM 内存区域与对象创建:一次 GC 从哪来
java·jvm·spring boot·spring·servlet·tomcat
m4Rk_29 分钟前
【论文阅读】Agent 记忆机制(77):TSM——让记忆回到事件真正发生的时间
论文阅读·人工智能·学习·开源·github
陈年老古董33 分钟前
MediaPipe 姿态检测与脸部关键点检测
笔记·python·opencv·学习·dlib
事圆则缓40 分钟前
Java 转 Kotlin 的 Android 迁移路线
java
旺仔小馒头wang41 分钟前
AI 智能手机发布会:赋予人类的五种新能力
人工智能·学习·音视频
人工智能培训42 分钟前
未来三年,AI 落地的五个确定性判断
大数据·人工智能·学习·生活·ai写作
计算机毕设定制辅导-无忧学长1 小时前
《基于Vue的流浪动物救助中心管理系统的设计与实现》
java·vue.js·spring boot·流浪动物救助中心管理系统