Java 解释器模式详解
解释器模式(Interpreter Pattern)是一种行为型设计模式,用于定义语言的文法规则,并解释该语言中的句子。

核心概念
主要角色:
- 抽象表达式(AbstractExpression):定义解释操作的接口
- 终结符表达式(TerminalExpression):实现文法中的终结符操作
- 非终结符表达式(NonterminalExpression):实现文法中的非终结符操作
- 上下文(Context):包含解释器需要的全局信息
- 客户端(Client):构建抽象语法树并调用解释操作
经典案例:算术表达式解释器
实现一个简单的加减法表达式解释器,支持数字和 、 运算符。
步骤1:定义抽象表达式接口
// 抽象表达式接口
interface Expression {
int interpret(Context context);
}
步骤2:创建终结符表达式(数字)
// 终结符表达式 - 数字
class NumberExpression implements Expression {
private int number;
public NumberExpression(int number) {
this.number = number;
}
@Override
public int interpret(Context context) {
return number;
}
}
步骤3:创建非终结符表达式(运算符)
// 非终结符表达式 - 加法
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(Context context) {
return left.interpret(context) + right.interpret(context);
}
}
// 非终结符表达式 - 减法
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(Context context) {
return left.interpret(context) - right.interpret(context);
}
}
步骤4:创建上下文类
// 上下文类(此处可扩展存储变量值等)
class Context {
// 这里可以存储变量值映射等信息
// Map<String, Integer> variables;
// 此简单例子中不需要特殊内容
}
步骤5:创建解析器(可选,用于将表达式字符串转为语法树)
// 解析器 - 将表达式字符串解析为语法树
class Parser {
public static Expression parse(String expression) {
// 简单解析:支持 "数字 运算符 数字" 格式
String[] parts = expression.split(" ");
if (parts.length == 3) {
Expression left = new NumberExpression(Integer.parseInt(parts[0]));
Expression right = new NumberExpression(Integer.parseInt(parts[2]));
switch (parts[1]) {
case "+":
return new AddExpression(left, right);
case "-":
return new SubtractExpression(left, right);
default:
throw new IllegalArgumentException("不支持的运算符: " + parts[1]);
}
}
throw new IllegalArgumentException("无效表达式格式");
}
}
步骤6:客户端测试
public class InterpreterPatternDemo {
public static void main(String[] args) {
Context context = new Context();
// 方式一:手动构建语法树
System.out.println("=== 手动构建语法树 ===");
Expression add = new AddExpression(
new NumberExpression(10),
new NumberExpression(5)
);
System.out.println("10 + 5 = " + add.interpret(context));
Expression subtract = new SubtractExpression(
new NumberExpression(20),
new NumberExpression(8)
);
System.out.println("20 - 8 = " + subtract.interpret(context));
// 复杂表达式: (10 + 5) - (20 - 8)
Expression complex = new SubtractExpression(
new AddExpression(
new NumberExpression(10),
new NumberExpression(5)
),
new SubtractExpression(
new NumberExpression(20),
new NumberExpression(8)
)
);
System.out.println("(10 + 5) - (20 - 8) = " + complex.interpret(context));
// 方式二:使用解析器
System.out.println("\n=== 使用解析器 ===");
Expression parsedAdd = Parser.parse("15 + 7");
System.out.println("15 + 7 = " + parsedAdd.interpret(context));
Expression parsedSub = Parser.parse("100 - 33");
System.out.println("100 - 33 = " + parsedSub.interpret(context));
}
}
运行结果:
=== 手动构建语法树 ===
10 + 5 = 15
20 - 8 = 12
(10 + 5) - (20 - 8) = 3
=== 使用解析器 ===
15 + 7 = 22
100 - 33 = 67
进阶案例:布尔表达式解释器
实现支持 AND、OR、NOT 的布尔表达式解释器。
// 上下文类
class BooleanContext {
private Map<String, Boolean> variables = new HashMap<>();
public void setVariable(String name, boolean value) {
variables.put(name, value);
}
public boolean getVariable(String name) {
return variables.getOrDefault(name, false);
}
}
// 抽象表达式
interface BooleanExpression {
boolean interpret(BooleanContext context);
}
// 变量表达式(终结符)
class VariableExpression implements BooleanExpression {
private String name;
public VariableExpression(String name) {
this.name = name;
}
@Override
public boolean interpret(BooleanContext context) {
return context.getVariable(name);
}
}
// 常量表达式(终结符)
class ConstantExpression implements BooleanExpression {
private boolean value;
public ConstantExpression(boolean value) {
this.value = value;
}
@Override
public boolean interpret(BooleanContext context) {
return value;
}
}
// AND 表达式(非终结符)
class AndExpression implements BooleanExpression {
private BooleanExpression left;
private BooleanExpression right;
public AndExpression(BooleanExpression left, BooleanExpression right) {
this.left = left;
this.right = right;
}
@Override
public boolean interpret(BooleanContext context) {
return left.interpret(context) && right.interpret(context);
}
}
// OR 表达式(非终结符)
class OrExpression implements BooleanExpression {
private BooleanExpression left;
private BooleanExpression right;
public OrExpression(BooleanExpression left, BooleanExpression right) {
this.left = left;
this.right = right;
}
@Override
public boolean interpret(BooleanContext context) {
return left.interpret(context) || right.interpret(context);
}
}
// NOT 表达式(非终结符)
class NotExpression implements BooleanExpression {
private BooleanExpression expression;
public NotExpression(BooleanExpression expression) {
this.expression = expression;
}
@Override
public boolean interpret(BooleanContext context) {
return !expression.interpret(context);
}
}
// 测试
public class BooleanInterpreterDemo {
public static void main(String[] args) {
BooleanContext context = new BooleanContext();
context.setVariable("A", true);
context.setVariable("B", false);
context.setVariable("C", true);
// (A AND B) OR (NOT B AND C)
BooleanExpression expr = new OrExpression(
new AndExpression(
new VariableExpression("A"),
new VariableExpression("B")
),
new AndExpression(
new NotExpression(new VariableExpression("B")),
new VariableExpression("C")
)
);
System.out.println("(A AND B) OR (NOT B AND C) where A=true, B=false, C=true");
System.out.println("Result: " + expr.interpret(context)); // true
}
}
实际应用场景
-
SQL 解析器
将 SQL 语句解析为语法树执行
-
正则表达式引擎
解释正则表达式模式匹配
-
数学表达式计算器
如公式引擎、科学计算器
-
配置文件解析
如 Spring 的 SpEL 表达式
-
脚本语言解释器
小型 DSL(领域特定语言)的实现
优缺点分析
优点:
- 易于扩展文法(添加新表达式类)
- 实现了文法分离,易于维护
- 可以方便地实现复杂表达式
缺点:
- 对于复杂文法,类层次会变得庞大
- 执行效率较低(递归调用)
- 不适合处理非常复杂的语言
最佳实践建议
- 使用时机:当需要解释简单语言且语法规则稳定时考虑使用
- 组合使用:常与组合模式一起使用构建语法树
- 性能优化:可以使用缓存或 Flyweight 模式优化
- 简化实现:对于简单场景,可以考虑使用脚本引擎(如 ScriptEngine)替代
解释器模式虽然不常用,但在需要自定义 DSL 或解析特定格式数据时非常有用,理解其原理有助于设计更灵活的架构。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播