(二 十 三)趣学设计模式 之 解释器模式!
目录
- 一、 啥是解释器模式?
- 二、 为什么要用解释器模式?
- 三、 解释器模式的实现方式
- 四、 解释器模式的优缺点
- 五、 解释器模式的应用场景
- 六、 总结
🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!
🌟了解备忘录模式请看: (二 十 二)趣学设计模式 之 备忘录模式!
这篇是设计模式专栏的最后一篇了,更多设计模式文章请看专栏 : ✨设计模式专栏
其他优质专栏: 【🎇SpringBoot】【🎉多线程】【🎨Redis】…等
如果喜欢作者的讲解方式,可以点赞收藏加关注,你的支持就是我的动力
✨更多文章请看个人主页: 码熔burning
一、 啥是解释器模式?
想象一下,你正在开发一个简单的计算器 🧮,你需要解析用户输入的算术表达式,比如 “1 + 2 * 3” ➕。 你需要将这个表达式分解成不同的部分,然后根据这些部分来计算结果。
解释器模式,给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子! 简单来说,就是定义一种语法规则,然后创建一个解释器来解析符合这种规则的语句 🗣️。
简单来说,就是创建一个“计算引擎”,将算术“表达式”翻译成计算机可以理解的计算指令! 🗣️+💻
- 你需要定义一种简单的语言: 就像你需要定义算术表达式的语法 ➕!
- 你需要解析这种语言的语句: 就像你需要解析 “1 + 2 * 3” 这个表达式 🧮!
- 你需要根据解析结果执行相应的操作: 就像你需要根据表达式计算出结果 7 ➗!
二、 为什么要用解释器模式?
用解释器模式,好处多多 👍:
- 易于扩展: 可以很容易地添加新的运算符 ➕!
- 灵活性高: 可以灵活地组合不同的运算符 🤸!
- 易于实现: 对于简单的表达式,实现起来比较容易 ✍️!
三、 解释器模式的实现方式
解释器模式主要包含以下几个角色:
- 抽象表达式(AbstractExpression): 声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享 🌳。
- 终结符表达式(TerminalExpression): 实现与文法中的终结符相关联的解释操作。一个句子中的每个终结符需要该类的一个实例 📍。
- 非终结符表达式(NonterminalExpression): 实现与文法中的非终结符相关联的解释操作。句子中的每条规则需要该类的一个实例 🔗。
- 上下文(Context): 包含解释器之外的一些全局信息 🌍。
- 客户端(Client): 构建表示特定句子的抽象语法树。然后调用解释操作 🧑💻。
代码示例:
import java.util.HashMap;
import java.util.Map;
// 抽象表达式:算术表达式
interface Expression {
int interpret(Map<String, Integer> variables); // 解释
}
// 终结符表达式:数字
class NumberExpression implements Expression {
private int number; // 数字
public NumberExpression(int number) {
this.number = number;
}
@Override
public int interpret(Map<String, Integer> variables) {
return number;
}
}
// 终结符表达式:变量
class VariableExpression implements Expression {
private String name; // 变量名
public VariableExpression(String name) {
this.name = name;
}
@Override
public int interpret(Map<String, Integer> variables) {
if (!variables.containsKey(name)) {
return 0; // 默认值为 0
}
return variables.get(name);
}
}
// 非终结符表达式:加法
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(Map<String, Integer> variables) {
return left.interpret(variables) + right.interpret(variables);
}
}
// 非终结符表达式:减法
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(Map<String, Integer> variables) {
return left.interpret(variables) - right.interpret(variables);
}
}
// 客户端
public class Client {
public static void main(String[] args) {
// 表达式:x + y - 10
VariableExpression x = new VariableExpression("x");
VariableExpression y = new VariableExpression("y");
NumberExpression ten = new NumberExpression(10);
Expression expression = new SubtractExpression(new AddExpression(x, y), ten);
// 上下文:变量赋值
Map<String, Integer> variables = new HashMap<>();
variables.put("x", 5);
variables.put("y", 8);
// 解释表达式
int result = expression.interpret(variables);
System.out.println("表达式: x + y - 10");
System.out.println("x = 5, y = 8");
System.out.println("结果:" + result);
}
}
分析:
Expression
是抽象表达式,定义了interpret
方法,用于解释表达式。NumberExpression
和VariableExpression
是终结符表达式,分别代表数字和变量,实现了interpret
方法,用于返回数字的值和变量的值。AddExpression
和SubtractExpression
是非终结符表达式,分别代表加法和减法,实现了interpret
方法,用于计算加法和减法的结果。
完整的输出结果:
表达式: x + y - 10
x = 5, y = 8
结果:3
四、 解释器模式的优缺点
优点:
- 易于扩展 ➕!
- 灵活性高 🤸!
- 易于实现 ✍️!
缺点:
- 对于复杂的语法,实现起来比较困难 🤯!
- 执行效率较低 🐌!
- 难以维护(当语法规则变得复杂时) 🚧!
五、 解释器模式的应用场景
- 需要定义一种简单的语言: 就像你需要定义算术表达式的语法 ➕!
- 需要解析这种语言的语句: 就像你需要解析 “1 + 2 * 3” 这个表达式 🧮!
- 需要根据解析结果执行相应的操作: 就像你需要根据表达式计算出结果 7 ➗!
- 例如:SQL 解析、正则表达式、编译器等 💻!
六、 总结
- 解释器模式就像创建一个“计算引擎”,将算术“表达式”翻译成计算机可以理解的计算指令! 🗣️+💻
- 优点是易于扩展、灵活性高、易于实现! 👍
- 缺点是对于复杂语法实现困难、执行效率低、难以维护! 👎
- 适用于需要定义一种简单的语言,并解析这种语言的语句的场景! 🎯
希望这个例子能让你彻底理解解释器模式! 💯 祝你学习愉快! 😄