public interface BooleanExpression { boolean interpret;}
public class ConstantBoolean implements BooleanExpression {
private final boolean value;public ConstantBoolean{ this.value=v;话说回来,}
public boolean interpret{ return value;}
}
public class VariableBoolean implements BooleanExpression{
private final String name;话说回来,public VariableBoolean{this.name=n;}
public boolean interpret{ return c.lookup;}
}
public class AndBoolean implements BooleanExpression{
private final BooleanExpression left,right;public AndBoolean{
this.left=l;this.right=r;}
public boolean interpret{
return left.interpret&&r.interpret;}
}
…老实说,
Main Demo:
// 上下文类
class Context{
Map m=new HashMap<>;void set{m.put;}
int get{return m.get;}
}
// 建立 的 AST
Rule expr = new And(
new GreaterThan,new GreaterOrEqual);Context ctx=new Context;ctx.set,ctx.set;System.out.println);// true
No code changes when a rule updates → lower MTTR for ops teams.
No duplicate logic across different rules → DRY principle upheld.
Easier unit test coverage by testing each Expression subclass independently.
.
Differentiation with Similar Patterns:
Pattern
Intent
Use Case Example
When to Choose It
Mediator vs Interpreter?/Composite vs Interpreter?按理说,/ Visitor vs Interpreter?其实,/ Strategy vs Interpreter?/,?. ) .
,Let's step back from here and craft concise bullet lists:
**Interpreter**
Build an AST that represents a language.
Each node knows how to evaluate itself via recursion.
Rules can be added/removed by simply adding/removing classes.
**Composite**
Tree structure used for hierarchical objects。not necessarily representing a language.
All nodes implement same interface but have different semantics unrelated to parsing.
**Visitor**
Traverses an already built tree to perform multiple operations on nodes.
Node classes contain only an accept method – no evaluation logic mselves.
**Strategy**
Encapsulates one algorithm per strategy. All strategies are flat .
Not suitable when rules need nested logical combinations like A AND.
So choose **Interpreter** when:
• You need a domain-specific language or DSL that can be edited at runtime.
• Rules are composed hierarchically.
• You want open/closed principle compliance without touching existing code.
常见错误 &
错误
痛点
对策
把解析和求值混在一起
难以
新运算符就要改 Parser 和 Eval 两处
分离职责,只建树→在节点里做运算
未考虑优先级
运算顺序错误导致结果不符合业务预期
使用多层解析函数
对极长输入使用递归
StackOverflowError 或 GC 垃圾
用循环或迭代替代递归;缓存 AST
忘记 Context 的线程安全
多线程环境下共享同一 Context 出现脏读
每次请求传入新的 Context 或使用 ThreadLocal
实际项目中的应用案例
Spring SpEL 表达式引擎
java
Parser p = new SpelParser;SpelNode root = p.parse;EvaluationContext ctx = new StandardEvaluationContext;Object result = root.evaluate;// true/false 根据实际数据返回
SpEL 内部就是典型的解释器实现。其实,
支持自定义函数、集合操作还有模板化拼接。
Apache Commons JEXL
java
JexlEngine engine = new JexlBuilder.create;JexlScript script = engine.createScript;不过,JexlContext ctx = new MapContext;ctx.set,ctx.set;ctx.set,Object res = script.execute;// 20
提供了轻量级 DSL。可嵌入到配置文件中,实现 “配置即改变”。
大多数场景可通过 JEXL 完成,而无需自己写 Parser。
正则引擎内部
正则匹配一样可以看成一种解释器:
Pattern p = Pattern.compile+c?"),Matcher m = p.matcher;m.matches,// true/false 根据内部 AST 判断是否匹配成功。