解释器模式,表达式求值的终极利器!

低功耗蓝牙项目,需要一块懂省电的板

思澈 SF32LB52 芯片,BLE 协议栈深度优化,上手即开发

想象一下,你要开发一个智能计算器,用户输入"(3+5)*2-1",程序就能自动计算出结果15。或者你要设计一个配置系统,支持类似"if user.age > 18 then allow"这样的规则语法。解释器模式就像是给你的程序装了一个"翻译官",能够理解和执行各种自定义的表达式和语言!

🤔 什么是解释器模式?

解释器模式(Interpreter Pattern)是一种行为型设计模式,它定义了一种语言的文法表示,并提供一个解释器来处理这种语言中的句子。

说人话就是:给你的程序装一个"语言大脑",让它能理解和执行自定义的表达式!

生活中的解释器模式

计算器就是最好的例子:

  • 你输入:“2 + 3 * 4”
  • 计算器理解:先算乘法(3*4=12),再算加法(2+12=14)
  • 最终输出:14

音乐播放器读乐谱

  • 乐谱上写着:♪ ♫ ♪ ♩
  • 播放器解释:四分音符 八分音符 四分音符 二分音符
  • 最终输出:对应的音乐

Google翻译

  • 输入:“Hello World”
  • 翻译器解释:英语句子,主语+宾语结构
  • 输出:“你好世界”

编程语言解释器

// Java代码
if (age > 18) {
    System.out.println("成年人");
}

// JVM解释器理解:
// 1. 条件判断语句
// 2. 比较age变量与常量18
// 3. 如果为真,执行打印语句

💼 解释器模式的应用场景

1. 数学表达式计算器

// 用户输入复杂的数学表达式
String expression = "(3 + 5) * 2 - 4 / 2";
Calculator calculator = new Calculator();
double result = calculator.evaluate(expression); // 结果:14.0

2. 业务规则引擎

// 电商系统的促销规则
String rule = "if (user.level == 'VIP' AND order.amount > 1000) then discount = 0.8";
RuleEngine engine = new RuleEngine();
boolean result = engine.evaluate(rule, context);

3. SQL查询解析

// 简化版SQL解析
String sql = "SELECT name, age FROM users WHERE age > 18";
SQLParser parser = new SQLParser();
QueryResult result = parser.execute(sql);

4. 配置文件解析

// 自定义配置语言
String config = """
    server {
        port = 8080
        host = "localhost"
        if env == "prod" then ssl = true
    }
    """;
ConfigParser parser = new ConfigParser();
Configuration conf = parser.parse(config);

在这里插入图片描述

⚙️ 解释器模式的核心原理

核心组件

  1. 抽象表达式(Abstract Expression):定义解释操作的接口
  2. 终结符表达式(Terminal Expression):实现语法中终结符相关的解释操作
  3. 非终结符表达式(Non-terminal Expression):实现语法中非终结符相关的解释操作
  4. 环境(Context):包含解释器之外的一些全局信息
  5. 客户端(Client):构建抽象语法树,调用解释操作

代码实现:数学表达式计算器

1. 抽象表达式接口
/**
 * 抽象表达式接口 - 解释器模式的核心
 */
public interface Expression {
    /**
     * 解释表达式,返回计算结果
     * @param context 上下文环境(可存储变量值等)
     * @return 表达式的计算结果
     */
    double interpret(Context context);
}
2. 上下文环境
/**
 * 上下文类 - 存储变量和全局信息
 */
public class Context {
    // 存储变量值,例如 x=10, y=20
    private Map<String, Double> variables = new HashMap<>();
    
    public void setVariable(String name, double value) {
        variables.put(name, value);
        System.out.println("📝 设置变量:" + name + " = " + value);
    }
    
    public double getVariable(String name) {
        Double value = variables.get(name);
        if (value == null) {
            throw new RuntimeException("未定义的变量: " + name);
        }
        System.out.println("🔍 获取变量:" + name + " = " + value);
        return value;
    }
    
    public boolean hasVariable(String name) {
        return variables.containsKey(name);
    }
    
    // 打印所有变量
    public void printVariables() {
        System.out.println("📋 当前变量:" + variables);
    }
}
3. 终结符表达式(数字和变量)
/**
 * 数字表达式 - 终结符表达式
 */
public class NumberExpression implements Expression {
    private double number;
    
    public NumberExpression(double number) {
        this.number = number;
        System.out.println("🔢 创建数字表达式:" + number);
    }
    
    @Override
    public double interpret(Context context) {
        System.out.println("📊 解释数字:" + number);
        return number;
    }
    
    @Override
    public String toString() {
        return String.valueOf(number);
    }
}

/**
 * 变量表达式 - 终结符表达式  
 */
public class VariableExpression implements Expression {
    private String variableName;
    
    public VariableExpression(String variableName) {
        this.variableName = variableName;
        System.out.println("🏷️  创建变量表达式:" + variableName);
    }
    
    @Override
    public double interpret(Context context) {
        double value = context.getVariable(variableName);
        System.out.println("📊 解释变量:" + variableName + " = " + value);
        return value;
    }
    
    @Override
    public String toString() {
        return variableName;
    }
}
4. 非终结符表达式(运算符)
/**
 * 加法表达式 - 非终结符表达式
 */
public class AddExpression implements Expression {
    private Expression left;
    private Expression right;
    
    public AddExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
        System.out.println("➕ 创建加法表达式:(" + left + " + " + right + ")");
    }
    
    @Override
    public double interpret(Context context) {
        double leftValue = left.interpret(context);
        double rightValue = right.interpret(context);
        double result = leftValue + rightValue;
        System.out.println("🧮 计算加法:" + leftValue + " + " + rightValue + " = " + result);
        return result;
    }
    
    @Override
    public String toString() {
        return "(" + left + " + " + right + ")";
    }
}

/**
 * 减法表达式 - 非终结符表达式
 */
public class SubtractExpression implements Expression {
    private Expression left;
    private Expression right;
    
    public SubtractExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
        System.out.println("➖ 创建减法表达式:(" + left + " - " + right + ")");
    }
    
    @Override
    public double interpret(Context context) {
        double leftValue = left.interpret(context);
        double rightValue = right.interpret(context);
        double result = leftValue - rightValue;
        System.out.println("🧮 计算减法:" + leftValue + " - " + rightValue + " = " + result);
        return result;
    }
    
    @Override
    public String toString() {
        return "(" + left + " - " + right + ")";
    }
}

/**
 * 乘法表达式 - 非终结符表达式
 */
public class MultiplyExpression implements Expression {
    private Expression left;
    private Expression right;
    
    public MultiplyExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
        System.out.println("✖️ 创建乘法表达式:(" + left + " * " + right + ")");
    }
    
    @Override
    public double interpret(Context context) {
        double leftValue = left.interpret(context);
        double rightValue = right.interpret(context);
        double result = leftValue * rightValue;
        System.out.println("🧮 计算乘法:" + leftValue + " * " + rightValue + " = " + result);
        return result;
    }
    
    @Override
    public String toString() {
        return "(" + left + " * " + right + ")";
    }
}

/**
 * 除法表达式 - 非终结符表达式
 */
public class DivideExpression implements Expression {
    private Expression left;
    private Expression right;
    
    public DivideExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
        System.out.println("➗ 创建除法表达式:(" + left + " / " + right + ")");
    }
    
    @Override
    public double interpret(Context context) {
        double leftValue = left.interpret(context);
        double rightValue = right.interpret(context);
        if (rightValue == 0) {
            throw new ArithmeticException("除数不能为零");
        }
        double result = leftValue / rightValue;
        System.out.println("🧮 计算除法:" + leftValue + " / " + rightValue + " = " + result);
        return result;
    }
    
    @Override
    public String toString() {
        return "(" + left + " / " + right + ")";
    }
}
5. 表达式解析器(语法分析器)
/**
 * 表达式解析器 - 将字符串转换为表达式树
 */
public class ExpressionParser {
    
    /**
     * 解析表达式字符串,构建表达式树
     * 支持的语法:数字、变量、+、-、*、/、括号
     * 运算符优先级:() > */ > +-
     */
    public Expression parse(String expression) {
        System.out.println("🔍 开始解析表达式:" + expression);
        
        // 去除空格
        expression = expression.replaceAll("\\s+", "");
        
        // 词法分析:将字符串分解为token
        List<String> tokens = tokenize(expression);
        System.out.println("📝 词法分析结果:" + tokens);
        
        // 语法分析:构建表达式树
        Expression result = parseExpression(tokens, 0).expression;
        System.out.println("🌲 表达式树构建完成:" + result);
        
        return result;
    }
    
    /**
     * 词法分析:将表达式分解为token
     */
    private List<String> tokenize(String expression) {
        List<String> tokens = new ArrayList<>();
        StringBuilder current = new StringBuilder();
        
        for (char c : expression.toCharArray()) {
            if (Character.isDigit(c) || c == '.') {
                current.append(c);
            } else if (Character.isLetter(c)) {
                current.append(c);
            } else {
                if (current.length() > 0) {
                    tokens.add(current.toString());
                    current.setLength(0);
                }
                tokens.add(String.valueOf(c));
            }
        }
        
        if (current.length() > 0) {
            tokens.add(current.toString());
        }
        
        return tokens;
    }
    
    /**
     * 语法分析结果包装类
     */
    private static class ParseResult {
        Expression expression;
        int nextIndex;
        
        ParseResult(Expression expression, int nextIndex) {
            this.expression = expression;
            this.nextIndex = nextIndex;
        }
    }
    
    /**
     * 解析表达式(处理 + 和 - 运算符)
     */
    private ParseResult parseExpression(List<String> tokens, int index) {
        ParseResult left = parseTerm(tokens, index);
        
        while (left.nextIndex < tokens.size()) {
            String operator = tokens.get(left.nextIndex);
            if (!operator.equals("+") && !operator.equals("-")) {
                break;
            }
            
            ParseResult right = parseTerm(tokens, left.nextIndex + 1);
            
            if (operator.equals("+")) {
                left.expression = new AddExpression(left.expression, right.expression);
            } else {
                left.expression = new SubtractExpression(left.expression, right.expression);
            }
            
            left.nextIndex = right.nextIndex;
        }
        
        return left;
    }
    
    /**
     * 解析项(处理 * 和 / 运算符)
     */
    private ParseResult parseTerm(List<String> tokens, int index) {
        ParseResult left = parseFactor(tokens, index);
        
        while (left.nextIndex < tokens.size()) {
            String operator = tokens.get(left.nextIndex);
            if (!operator.equals("*") && !operator.equals("/")) {
                break;
            }
            
            ParseResult right = parseFactor(tokens, left.nextIndex + 1);
            
            if (operator.equals("*")) {
                left.expression = new MultiplyExpression(left.expression, right.expression);
            } else {
                left.expression = new DivideExpression(left.expression, right.expression);
            }
            
            left.nextIndex = right.nextIndex;
        }
        
        return left;
    }
    
    /**
     * 解析因子(处理数字、变量和括号)
     */
    private ParseResult parseFactor(List<String> tokens, int index) {
        if (index >= tokens.size()) {
            throw new RuntimeException("表达式不完整");
        }
        
        String token = tokens.get(index);
        
        // 处理括号
        if (token.equals("(")) {
            ParseResult result = parseExpression(tokens, index + 1);
            if (result.nextIndex >= tokens.size() || !tokens.get(result.nextIndex).equals(")")) {
                throw new RuntimeException("缺少右括号");
            }
            return new ParseResult(result.expression, result.nextIndex + 1);
        }
        
        // 处理数字
        if (isNumber(token)) {
            return new ParseResult(new NumberExpression(Double.parseDouble(token)), index + 1);
        }
        
        // 处理变量
        if (isVariable(token)) {
            return new ParseResult(new VariableExpression(token), index + 1);
        }
        
        throw new RuntimeException("无法识别的token: " + token);
    }
    
    private boolean isNumber(String token) {
        try {
            Double.parseDouble(token);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }
    
    private boolean isVariable(String token) {
        return token.matches("[a-zA-Z][a-zA-Z0-9]*");
    }
}
6. 计算器客户端
/**
 * 智能计算器 - 客户端类
 */
public class SmartCalculator {
    
    private ExpressionParser parser;
    private Context context;
    
    public SmartCalculator() {
        this.parser = new ExpressionParser();
        this.context = new Context();
        System.out.println("🧮 智能计算器启动成功!");
    }
    
    /**
     * 设置变量值
     */
    public void setVariable(String name, double value) {
        context.setVariable(name, value);
    }
    
    /**
     * 计算表达式
     */
    public double calculate(String expression) {
        System.out.println("\n" + "=".repeat(50));
        System.out.println("🎯 计算表达式:" + expression);
        System.out.println("=".repeat(50));
        
        try {
            // 解析表达式
            Expression expr = parser.parse(expression);
            
            // 解释执行
            System.out.println("\n🚀 开始执行计算...");
            double result = expr.interpret(context);
            
            System.out.println("\n✅ 计算完成!");
            System.out.println("📊 最终结果:" + expression + " = " + result);
            
            return result;
        } catch (Exception e) {
            System.err.println("❌ 计算出错:" + e.getMessage());
            throw e;
        }
    }
    
    /**
     * 打印变量列表
     */
    public void printVariables() {
        context.printVariables();
    }
    
    public static void main(String[] args) {
        SmartCalculator calculator = new SmartCalculator();
        
        System.out.println("🧪 === 智能计算器测试 === 🧪\n");
        
        // 测试1:简单四则运算
        System.out.println("📋 测试1:基础四则运算");
        calculator.calculate("3 + 5");
        calculator.calculate("10 - 4");
        calculator.calculate("6 * 7");
        calculator.calculate("15 / 3");
        
        // 测试2:复合运算(运算符优先级)
        System.out.println("\n📋 测试2:运算符优先级");
        calculator.calculate("3 + 5 * 2");      // 应该是 3 + (5 * 2) = 13
        calculator.calculate("10 - 4 / 2");     // 应该是 10 - (4 / 2) = 8
        calculator.calculate("2 * 3 + 4 * 5");  // 应该是 (2 * 3) + (4 * 5) = 26
        
        // 测试3:括号运算
        System.out.println("\n📋 测试3:括号改变运算顺序");
        calculator.calculate("(3 + 5) * 2");    // 应该是 8 * 2 = 16
        calculator.calculate("10 / (4 - 2)");   // 应该是 10 / 2 = 5
        calculator.calculate("((2 + 3) * 4) - (6 / 2)"); // ((5) * 4) - (3) = 17
        
        // 测试4:变量运算
        System.out.println("\n📋 测试4:变量支持");
        calculator.setVariable("x", 10);
        calculator.setVariable("y", 5);
        calculator.printVariables();
        
        calculator.calculate("x + y");           // 10 + 5 = 15
        calculator.calculate("x * y - 10");      // 10 * 5 - 10 = 40
        calculator.calculate("(x + y) * 2");     // (10 + 5) * 2 = 30
        
        // 测试5:复杂表达式
        System.out.println("\n📋 测试5:复杂表达式");
        calculator.setVariable("a", 2);
        calculator.setVariable("b", 3);
        calculator.setVariable("c", 4);
        
        calculator.calculate("a * b + c");               // 2 * 3 + 4 = 10
        calculator.calculate("(a + b) * c - a");         // (2 + 3) * 4 - 2 = 18
        calculator.calculate("a * (b + c) / (a + 1)");   // 2 * (3 + 4) / (2 + 1) = 14/3 ≈ 4.67
        
        System.out.println("\n🎉 所有测试完成!");
        
        // 性能测试
        System.out.println("\n⚡ 性能测试:");
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            calculator.calculate("(10 + 5) * 2 - 3");
        }
        long endTime = System.currentTimeMillis();
        System.out.println("执行1000次复杂表达式耗时:" + (endTime - startTime) + "毫秒");
    }
}

在这里插入图片描述

🚀 解释器模式的扩展应用

1. Spring表达式语言(SpEL)

Spring中的SpEL就是解释器模式的经典应用:

@Component
public class SpELDemo {
    
    @Value("#{systemProperties['java.version']}")
    private String javaVersion;
    
    @Value("#{T(java.lang.Math).random() * 100}")
    private double randomNumber;
    
    // 在代码中使用SpEL
    public void demonstrateSpEL() {
        ExpressionParser parser = new SpelExpressionParser();
        StandardEvaluationContext context = new StandardEvaluationContext();
        
        // 设置变量
        context.setVariable("user", new User("张三", 25));
        
        // 解析并执行表达式
        Expression exp = parser.parseExpression("#user.name + ' 今年 ' + #user.age + ' 岁'");
        String result = exp.getValue(context, String.class);
        System.out.println(result); // 输出:张三 今年 25 岁
        
        // 条件表达式
        Expression condExp = parser.parseExpression("#user.age >= 18 ? '成年人' : '未成年'");
        String ageCategory = condExp.getValue(context, String.class);
        System.out.println(ageCategory); // 输出:成年人
    }
}

2. 正则表达式引擎

正则表达式本质上也是解释器模式:

/**
 * 简化版正则表达式解释器
 */
public class SimpleRegexInterpreter {
    
    public static void main(String[] args) {
        // Java内置的正则表达式引擎
        Pattern pattern = Pattern.compile("\\d{3}-\\d{4}-\\d{4}");
        Matcher matcher = pattern.matcher("136-1234-5678");
        
        System.out.println("匹配结果:" + matcher.matches());
        
        // 自定义简单的模式匹配
        SimplePattern simplePattern = new SimplePattern("a*b");
        System.out.println("匹配 'aaab':" + simplePattern.matches("aaab"));
        System.out.println("匹配 'ab':" + simplePattern.matches("ab"));
        System.out.println("匹配 'b':" + simplePattern.matches("b"));
    }
}

class SimplePattern {
    private String pattern;
    
    public SimplePattern(String pattern) {
        this.pattern = pattern;
    }
    
    public boolean matches(String input) {
        // 简化的模式匹配逻辑(这里只是示例)
        if (pattern.equals("a*b")) {
            return input.matches("a*b");
        }
        return false;
    }
}

3. SQL解析器

SQL解析也是解释器模式的典型应用:

/**
 * 简化版SQL解释器
 */
public class SimpleSQLInterpreter {
    
    // SQL表达式接口
    interface SQLExpression {
        void execute(DatabaseContext context);
    }
    
    // SELECT语句
    static class SelectStatement implements SQLExpression {
        private List<String> columns;
        private String tableName;
        private WhereClause whereClause;
        
        public SelectStatement(List<String> columns, String tableName, WhereClause whereClause) {
            this.columns = columns;
            this.tableName = tableName;
            this.whereClause = whereClause;
        }
        
        @Override
        public void execute(DatabaseContext context) {
            System.out.println("🔍 执行查询:");
            System.out.println("   表名:" + tableName);
            System.out.println("   字段:" + columns);
            if (whereClause != null) {
                System.out.println("   条件:" + whereClause);
            }
            
            // 模拟查询执行
            List<Map<String, Object>> results = context.query(tableName, columns, whereClause);
            System.out.println("   结果:" + results.size() + " 条记录");
        }
    }
    
    // WHERE子句
    static class WhereClause {
        private String condition;
        
        public WhereClause(String condition) {
            this.condition = condition;
        }
        
        @Override
        public String toString() {
            return condition;
        }
    }
    
    // 数据库上下文
    static class DatabaseContext {
        public List<Map<String, Object>> query(String table, List<String> columns, WhereClause where) {
            // 模拟数据库查询
            return Arrays.asList(
                Map.of("id", 1, "name", "张三", "age", 25),
                Map.of("id", 2, "name", "李四", "age", 30)
            );
        }
    }
    
    public static void main(String[] args) {
        // 构建SQL表达式
        List<String> columns = Arrays.asList("name", "age");
        WhereClause where = new WhereClause("age > 18");
        SelectStatement select = new SelectStatement(columns, "users", where);
        
        // 执行SQL
        DatabaseContext context = new DatabaseContext();
        select.execute(context);
    }
}

4. 配置文件解析器

/**
 * 配置文件解释器
 */
public class ConfigInterpreter {
    
    // 配置表达式接口
    interface ConfigExpression {
        void apply(ApplicationContext context);
    }
    
    // 服务器配置
    static class ServerConfig implements ConfigExpression {
        private int port;
        private String host;
        
        public ServerConfig(int port, String host) {
            this.port = port;
            this.host = host;
        }
        
        @Override
        public void apply(ApplicationContext context) {
            context.setServerPort(port);
            context.setServerHost(host);
            System.out.println("🌐 配置服务器:" + host + ":" + port);
        }
    }
    
    // 数据库配置
    static class DatabaseConfig implements ConfigExpression {
        private String url;
        private String username;
        
        public DatabaseConfig(String url, String username) {
            this.url = url;
            this.username = username;
        }
        
        @Override
        public void apply(ApplicationContext context) {
            context.setDatabaseUrl(url);
            context.setDatabaseUsername(username);
            System.out.println("🗄️  配置数据库:" + url + " (" + username + ")");
        }
    }
    
    // 应用上下文
    static class ApplicationContext {
        private int serverPort;
        private String serverHost;
        private String databaseUrl;
        private String databaseUsername;
        
        // Setters
        public void setServerPort(int port) { this.serverPort = port; }
        public void setServerHost(String host) { this.serverHost = host; }
        public void setDatabaseUrl(String url) { this.databaseUrl = url; }
        public void setDatabaseUsername(String username) { this.databaseUsername = username; }
        
        public void printConfig() {
            System.out.println("\n📋 应用配置总览:");
            System.out.println("   服务器:" + serverHost + ":" + serverPort);
            System.out.println("   数据库:" + databaseUrl + " (" + databaseUsername + ")");
        }
    }
    
    public static void main(String[] args) {
        // 解析配置文件
        List<ConfigExpression> configs = Arrays.asList(
            new ServerConfig(8080, "localhost"),
            new DatabaseConfig("jdbc:mysql://localhost:3306/mydb", "admin")
        );
        
        // 应用配置
        ApplicationContext context = new ApplicationContext();
        configs.forEach(config -> config.apply(context));
        
        context.printConfig();
    }
}

🎯 面试热点问题

Q1: 解释器模式和策略模式有什么区别?

面试官经常问的问题!

对比维度解释器模式策略模式
设计目的定义语言文法,解释语句定义算法族,相互替换
结构复杂度复杂,需要语法树简单,一个接口多个实现
使用场景需要解释执行表达式/语言需要动态选择算法
扩展性难扩展,修改文法影响大易扩展,添加新策略简单

记忆技巧:

  • 解释器模式:翻译官,把一种语言翻译成另一种
  • 策略模式:工具箱,根据需要选择不同的工具

Q2: 解释器模式的优缺点?

优点:

  • 易于实现语法:每个语法规则对应一个类,结构清晰
  • 易于扩展语法:增加新的语法规则只需要添加新类
  • 易于修改和扩展:每个表达式类独立,互不影响

缺点:

  • 类的数量增加:每个语法规则都需要一个类
  • 执行效率较低:递归调用,性能不如直接编译
  • 适用范围有限:只适合简单的语法,复杂语法会导致类爆炸

Q3: 何时使用解释器模式?

适用场景:

  1. 简单语法:语言的语法相对简单
  2. 执行效率不是关键:不需要高性能的执行速度
  3. 频繁变化的语法:语法规则经常需要修改和扩展
  4. 自定义DSL:需要实现特定领域的小语言

经典应用:

  • 数学表达式计算器
  • 简单的脚本语言解释器
  • 配置文件解析器
  • 正则表达式引擎
  • SQL解析器

不适用场景:

  • 复杂的编程语言(如Java、C++)
  • 对性能要求极高的场景
  • 语法规则过于复杂的情况

Q4: 解释器模式在开源框架中的应用?

1. Spring表达式语言(SpEL)

// Spring中大量使用SpEL解释器
@Value("#{configProperties.timeout ?: 5000}")
private int timeout;

@PreAuthorize("hasRole('ADMIN') and #user.department == 'IT'")
public void adminOperation(User user) { ... }

2. Apache Commons JEXL

// 数学表达式解释器
JexlEngine jexl = new JexlBuilder().create();
JexlExpression e = jexl.createExpression("foo.innerFoo.bar()");
JexlContext jc = new MapContext();
jc.set("foo", new Foo());
Object o = e.evaluate(jc);

3. Drools规则引擎

// 业务规则表达式
rule "Discount"
when
    $order : Order(amount > 1000)
    $customer : Customer(level == "VIP")
then
    $order.setDiscount(0.1);
end

Q5: 如何优化解释器模式的性能?

优化策略:

1. 缓存表达式树

public class CachedExpressionParser {
    private Map<String, Expression> cache = new ConcurrentHashMap<>();
    
    public Expression parse(String expression) {
        return cache.computeIfAbsent(expression, this::doParse);
    }
    
    private Expression doParse(String expression) {
        // 实际的解析逻辑
        return new ExpressionParser().parse(expression);
    }
}

2. 预编译表达式

public class CompiledExpression {
    private final Expression expression;
    private final Set<String> variables;
    
    public CompiledExpression(String expr) {
        this.expression = parser.parse(expr);
        this.variables = extractVariables(expr);
    }
    
    public double evaluate(Map<String, Double> values) {
        Context context = new Context();
        variables.forEach(var -> context.setVariable(var, values.get(var)));
        return expression.interpret(context);
    }
}

3. 使用访问者模式优化

// 将解释逻辑从表达式类中分离出来
public interface ExpressionVisitor {
    double visitNumber(NumberExpression expr);
    double visitAdd(AddExpression expr);
    double visitMultiply(MultiplyExpression expr);
}

public class OptimizedInterpreter implements ExpressionVisitor {
    // 优化的解释逻辑
    @Override
    public double visitAdd(AddExpression expr) {
        return expr.getLeft().accept(this) + expr.getRight().accept(this);
    }
}

💡 总结

解释器模式就像是给你的程序装了一个"语言大脑",让它能理解和执行各种自定义的表达式和语言!

记住这个口诀:

语法规则对应类,表达式树递归推

简单语言解释器,DSL实现靠它追!

实战建议:

  1. 识别适用场景:简单语法 + 性能要求不高 + 需要灵活扩展
  2. 合理设计文法:保持语法简单,避免过度复杂
  3. 考虑性能优化:使用缓存、预编译等技术
  4. 结合其他模式:可以与访问者模式、工厂模式结合使用

解释器模式不仅仅是一种设计模式,更是一种语言处理的编程思想。当你需要创建自己的小语言或表达式系统时,解释器模式就是你的最佳选择!


看完这篇文章,下次遇到需要解析表达式的需求时,记得想想解释器模式!让你的程序从"哑巴"变成"语言大师"~ 记得点赞👍收藏⭐分享🔄!

低功耗蓝牙项目,需要一块懂省电的板

思澈 SF32LB52 芯片,BLE 协议栈深度优化,上手即开发

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慢德

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值