学习设计模式之解释器模式
解释器模式
定义一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
类结构图
Context
包含解释之外的一些全局信息。
AbstractExpression
声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。
TerminalExpression
终结符表达式,实现与文法中的终结符相关联的解释操作。
NonterminalExpression
非终结符表达式,为文法中的非终结符实现解释操作。
代码示例
乐谱大家都见过,那么我们来自定义一下 O 表示音阶、C D E F G A B 表示 Do-Re-Mi-Fa-So-La-Ti。
public class Context {
private String playText;
public String getPlayText() {
return playText;
}
public void setPlayText(String playText) {
this.playText = playText;
}
}
public abstract class Expression {
abstract void excute(String key, String value);
public void interpret(Context context) {
if (null == context.getPlayText() || "".equals(context.getPlayText())) {
return;
}
// 解析的字符串例如 O 3 E 0.5
String playKey = context.getPlayText().substring(0, 1);
context.setPlayText(context.getPlayText().substring(2));
String value = context.getPlayText().substring(0, context.getPlayText().indexOf(" "));
context.setPlayText(context.getPlayText().substring(context.getPlayText().indexOf(" ") + 1));
excute(playKey, value);
}
}
public class Note extends Expression {
@Override
void excute(String key, String value) {
String note = "";
switch (key) {
case "C":
note = "1";
break;
case "D":
note = "2";
break;
case "E":
note = "3";
break;
case "F":
note = "4";
break;
case "G":
note = "5";
break;
case "A":
note = "6";
break;
case "B":
note = "7";
break;
}
System.out.print(note + "\t");
}
}
public class Scale extends Expression {
@Override
void excute(String key, String value) {
String scale = "";
switch (Integer.parseInt(value)) {
case 1:
scale = "低音";
break;
case 2:
scale = "中音";
break;
case 3:
scale = "高音";
break;
}
System.out.print(scale + "\t");
}
}
客户端示例
public class ExpressionClient {
public static void main(String[] args) {
Context context = new Context();
context.setPlayText(
"O 2 E null G null A 3 E null G null D 3 E null G null A null O 3 C 1 O 2 A null G 1 C null E null E 3 ");
Expression expression = null;
while (context.getPlayText().length() > 0) {
String str = context.getPlayText().substring(0, 1);
switch (str) {
case "O":
expression = new Scale();
break;
case "C":
case "D":
case "E":
case "F":
case "G":
case "A":
case "B":
case "P":
expression = new Note();
break;
}
expression.interpret(context);
}
}
}
运行结果
中音 3 5 6 3 5 2 3 5 6 高音 1 中音 6 5 1 3 3
Process finished with exit code 0
优点
可以比较方便的修改和扩展语法规则。
缺点
几乎针对每一个规则都定义了一个类,所以如果一个语法的规则比较多,那对于语法的维护工作也会变得非常困难。
勿在浮沙筑高台
——个人浅见,难免有误导之处,麻烦请指出。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· 手把手教你更优雅的享受 DeepSeek
· 腾讯元宝接入 DeepSeek R1 模型,支持深度思考 + 联网搜索,好用不卡机!
· AI工具推荐:领先的开源 AI 代码助手——Continue
· 探秘Transformer系列之(2)---总体架构
· V-Control:一个基于 .NET MAUI 的开箱即用的UI组件库