解释器模式

介绍

**定义:**用于定义语言的语法规则并提供解释器来处理语句中的语法. 该模式使用频率并不高, 只会在一些特定的领域中用到. 通常用来描述如何构建一个简单的语言语法解释器, 如正则表达式/SQL解析等.

UML

示例

java 复制代码
package com.sumlv.demo;

import com.sumlv.demo.interperter.CalculateExpressionInterperter;

public class Main {

    public static void main(String[] args) {
        CalculateExpressionInterperter interperter = new CalculateExpressionInterperter();
        Integer result = interperter.interpret("1 + 2 - 3", " ");
        
        System.out.println(result);
    }

}
java 复制代码
package com.sumlv.demo.interperter;

import java.util.*;

/**
 * 运算表达式解释器
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-04-01
 */
public class CalculateExpressionInterperter {

    private static final List<String> LEGAL_OPERATOR = new ArrayList<>(){{
       add(SubtractExpression.SYMBOL);
       add(PlusExpression.SYMBOL);
    }};

    public Integer interpret(String expression, String split) {
        String[] expressions = expression.split(split);
        Deque<Expression> numbers = new LinkedList<>();
        List<String> operators = new ArrayList<>();

        this.classify(expressions, operators, numbers);

        for (String operator : operators) {
            Expression expression1 = numbers.pollFirst();
            Expression expression2 = numbers.pollFirst();

            if (expression2 == null) {
                break;
            }

            switch (operator) {
                case SubtractExpression.SYMBOL:
                    numbers.addFirst(new SubtractExpression(expression1, expression2));
                case PlusExpression.SYMBOL:
                    numbers.addFirst(new PlusExpression(expression1, expression2));
            }
        }

        return numbers.pollFirst().interpret();
    }


    private void classify(String[] expressions, List<String> operators, Deque<Expression> numbers) {
        for (String expression : expressions) {
            if (!this.isLegalExpression(expression)) {
                throw new RuntimeException("non legal expression");
            }

            if (this.isOperator(expression)) {
                operators.add(expression);
            } else {
                numbers.addLast(new IntExpression(expression));
            }
        }
    }

    private Boolean isLegalExpression(String expression) {
        return this.isOperator(expression) || this.isInt(expression);
    }

    private Boolean isOperator(String expression) {
        return CalculateExpressionInterperter.LEGAL_OPERATOR.contains(expression);
    }

    private Boolean isInt(String expression) {
        try {
            Integer.parseInt(expression);
            return Boolean.TRUE;
        } catch (NumberFormatException e) {
            return Boolean.FALSE;
        }
    }


}
java 复制代码
package com.sumlv.demo.interperter;

/**
 * 表达式
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-04-01
 */
public interface Expression {

    int interpret();

}
java 复制代码
package com.sumlv.demo.interperter;

/**
 * 整数表达式
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-04-01
 */
public class IntExpression implements Expression{

    private final int number;

    public IntExpression(String number) {
        this.number = Integer.parseInt(number);
    }

    @Override
    public int interpret() {
        return this.number;
    }

}
java 复制代码
package com.sumlv.demo.interperter;

/**
 * 加法表达式
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-04-01
 */
public class PlusExpression implements Expression{

    public static final String SYMBOL = "+";

    private final Expression number1;

    private final Expression number2;

    public PlusExpression(Expression number1, Expression number2) {
        this.number1 = number1;
        this.number2 = number2;
    }

    @Override
    public int interpret() {
        return this.number1.interpret() + this.number2.interpret();
    }

}
java 复制代码
package com.sumlv.demo.interperter;

/**
 * 减法表达式
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-04-01
 */
public class SubtractExpression implements Expression{

    public static final String SYMBOL = "-";

    private final Expression number1;

    private final Expression number2;

    public SubtractExpression(Expression number1, Expression number2) {
        this.number1 = number1;
        this.number2 = number2;
    }

    @Override
    public int interpret() {
        return this.number1.interpret() - this.number2.interpret();
    }

}

总结

使用场景

  1. 当表达式的语法并不复杂且不关心执行效率时;

  2. 当某场景频繁出现且可以用表达式归纳时.

优点:

  1. 可以快速实现一套自定义的迷你语言;

  2. 易于拓展(新增语法规则时直接增加新的表达式类即可, 无需修改原有代码, 符合开闭原则).

缺点:

  1. 难以维护复杂语法(由于每条规则都需要定义表达式类, 复杂语法会使类的数量急剧增加使系统难以维护);

  2. 执行效率低(语法的解释过程用到了大量的循环或递归, 直接影响程序运行效率).

相关推荐
Yu_Lijing7 天前
基于C++的《Head First设计模式》笔记——解释器模式
c++·设计模式·解释器模式
夕珩20 天前
单例模式、原型模式、工厂方法模式、抽象工厂模式、建造者模式、解释器模式、命令模式
单例模式·解释器模式·建造者模式·工厂方法模式·抽象工厂模式·命令模式·原型模式
逆境不可逃21 天前
【从零入门23种设计模式15】行为型之解释器模式
设计模式·解释器模式
资深web全栈开发1 个月前
设计模式之解释器模式 (Interpreter Pattern)
设计模式·解释器模式
YigAin2 个月前
Unity23种设计模式之 解释器模式
设计模式·解释器模式
Engineer邓祥浩2 个月前
设计模式学习(22) 23-20 解释器模式
学习·设计模式·解释器模式
小飞侠hello2 个月前
解释器模式
解释器模式
小码过河.2 个月前
设计模式——解释器模式
java·设计模式·解释器模式
会员果汁2 个月前
23.设计模式-解释器模式
设计模式·解释器模式