概念
为特定类型的语言提供解释执行的方法,能够根据输入的特定指令完成一些列操作
应用场景
当需要处理用户自定义的、结构清晰的表达式或指令时,用硬编码的方式去处理各种情况,不仅代码臃肿,而且非常难维护。
使用解释器模式后能够将语法规则和执行逻辑封装到各个解释器对象中,既符合开闭原则,也让系统更容易维护和扩展
基本结构

1)表达式接口(AbstractExpression):定义所有解释器的通用接口,通常包含一个interpret()方法,负责解释和计算表达式
2)终结符表达式(TerminalExpression):实现interpret()方法的具体类,表示具体的语法元素。这些元素是无法再分解的最小单位
3)非终结符表达式(NonTerminalExpression):与终结符表达式不同,它们用于表示语言中的组合元素,可以包含其他表达式作为其子表达式
4)上下文(Context):包含了解释过程中所需要的数据,例如变量的值或当前的环境
5)客户端(Client):客户端负责构建并初始化解释器中的表达式,给定输入后,启动解释过程
代码实现
以 “自定义规则引擎” 为例,执行类似 age > 18 && score < 500 这样的规则表达式
表达式接口
声明规则表达式的执行方法
每一个表达式类都要包含一个执行当前表达式的方法
public interface Expression {
boolean interpret(Context context); // 解释表达式,返回布尔值
}
上下文
存储规则所需要的参数
public class Context {
private int age;
private int score;
public Context(int age, int score) {
this.age = age;
this.score = score;
}
public int getAge() {
return age;
}
public int getScore() {
return score;
}
}
终结符表达式
实现具体的每一小部分的规则
public class GreaterThanExpression implements Expression {
private String field;
private int value;
public GreaterThanExpression(String field, int value) {
this.field = field;
this.value = value;
}
@Override
public boolean interpret(Context context) {
if ("age".equals(field)) {
return context.getAge() > value;
} else if ("score".equals(field)) {
return context.getScore() > value;
}
return false;
}
}
public class LessThanExpression implements Expression {
private String field;
private int value;
public LessThanExpression(String field, int value) {
this.field = field;
this.value = value;
}
@Override
public boolean interpret(Context context) {
if ("age".equals(field)) {
return context.getAge() < value;
} else if ("score".equals(field)) {
return context.getScore() < value;
}
return false;
}
}
非终结符表达式
由多个终结符表达式或非终结符表达式组成的一串表达式
执行时递归地执行
public class AndExpression implements Expression {
private Expression expr1;
private Expression expr2;
public AndExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
@Override
public boolean interpret(Context context) {
return expr1.interpret(context) && expr2.interpret(context);
}
}
解析表达式类
能够将用户输入的指令解析为表达式类
public class RuleParser {
public static Expression parse(String rule) {
String[] tokens = rule.split("&&"); // 按“&&”分割表达式
Expression left = null;
Expression right = null;
for (String token : tokens) {
token = token.trim();
if (token.contains(">")) {
String[] parts = token.split(">");
String field = parts[0].trim();
int value = Integer.parseInt(parts[1].trim());
left = new GreaterThanExpression(field, value);
} else if (token.contains("<")) {
String[] parts = token.split("<");
String field = parts[0].trim();
int value = Integer.parseInt(parts[1].trim());
right = new LessThanExpression(field, value);
}
}
return new AndExpression(left, right); // 合并左右表达式
}
}
客户端调用
public class Client {
public static void main(String[] args) {
// 用户输入的动态规则
String rule = "age > 18 && score < 500";
// 创建上下文对象
Context context = new Context(20, 450); // 假设 age = 20, score = 450
// 解析规则表达式
Expression expression = RuleParser.parse(rule);
// 判断规则是否成立
boolean result = expression.interpret(context);
System.out.println("表达式结果: " + result); // 输出结果
}
}
优缺点
优点
1)容易扩展:有新的语法需求,就可以在原有基础上添加新的解释器类
2)结构清晰:将不同的语法规则和解释逻辑分开
缺点
1)不适合简单场景:语法规则非常简单,使用解释器模式可能就显得有些过于复杂
