概述:解释器模式 := Interpreter Pattern ∈ 行为型模式

模式定义

  • 解释器模式Interpreter Pattern)提供了评估语言的语法表达式的方式

属于行为型模式

  • 解释器模式给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子

  • 这种模式被用在 SQL 解析符号处理引擎等。

  • 模式的意图

定义一种语言的文法表示,并创建一个解释器,该解释器能够解释该语言中的句子。。

  • 主要解决的问题

解释器模式用于构建一个能够解释特定语言或文法句子的解释器

模式结构

解释器模式包含以下几个主要角色:

  • 抽象表达式(Abstract Expression):定义了解释器的抽象接口,声明了解释操作的方法,通常是一个抽象类或接口。
  • 终结符表达式(Terminal Expression):实现了抽象表达式接口的终结符表达式类,用于表示语言中的终结符(如变量、常量等),并实现了对应的解释操作。
  • 非终结符表达式(Non-terminal Expression):实现了抽象表达式接口的非终结符表达式类,用于表示语言中的非终结符(如句子、表达式等),并实现了对应的解释操作。
  • 上下文(Context):包含解释器之外的一些全局信息,在解释过程中提供给解释器使用,通常用于存储变量的值、保存解释器的状态等。
  • 客户端(Client):创建并配置具体的解释器对象,并将需要解释的表达式传递给解释器进行解释。

适用场景

  • 当某一特定类型的问题频繁出现,并且可以通过一种简单的语言来表达这些问题的实例时。

实现方式

  • 定义【文法】:明确语言的终结符和非终结符。
  • 构建【语法树】:根据语言的句子构建对应的语法树结构。
  • 创建【环境类】:包含解释过程中所需的全局信息,通常是一个HashMap。

关键代码

  • 终结符与非终结符:定义语言的文法结构。
  • 环境类:存储解释过程中需要的外部环境信息。

模式特点

优点

  • 可扩展性好:容易添加新的解释表达式的方式。
  • 灵活性:可以根据需要轻松扩展或修改文法。
  • 易于实现简单文法:对于简单的语言,实现起来相对容易。

缺点

  1. 使用场景有限:只适用于适合使用解释的简单文法。
  2. 维护困难:对于复杂的文法,维护和扩展变得困难。
  3. 类膨胀:可能会产生很多类,每个文法规则对应一个类。
  4. 递归调用:解释器模式通常使用【递归调用】,这可能难以理解和跟踪。

使用建议

  • 在需要解释执行语言中的句子时,考虑使用解释器模式。
  • 确保文法简单,以避免系统变得过于复杂。
  • 解释器模式在 Java 中可能不是首选,如果遇到适用场景,可以考虑使用如expression4J之类的库来代替。

案例实践

案例总结

  • 编译器:解释器模式可以用于编译器设计,将源代码解释为目标代码。
  • 正则表达式:解释器模式可以用于解析和执行正则表达式。
  • SQL解析:解释器模式可以用于解析和执行SQL语句。
  • 文本模板渲染引擎 : 用于将各层级的环境信息渲染到文本模板中,生成最终的SQL、HTML等。著名的文本模板渲染引擎有:Jinjia(2) / Thymeleaf / Freemaker 等。

CASE 解释器模式的简单实现(性别/婚姻)

  • 我们将创建一个接口 Expression 和实现了 Expression 接口的实体类。
  • 定义作为上下文中主要解释器的 TerminalExpression 类。
  • 其他的类 OrExpression、AndExpression 用于创建组合式表达式
  • InterpreterPatternDemo,我们的演示类使用 Expression 类创建规则和演示表达式的解析。

表达式接口 : Expression

public interface Expression {
public boolean interpret(String context);
}

表达式接口的实现类: TerminalExpression / OrExpression / AndExpression

  • TerminalExpression
public class TerminalExpression implements Expression {

   private String data;

   public TerminalExpression(String data){
this.data = data;
} @Override
public boolean interpret(String context) {
if(context.contains(data)){
return true;
}
return false;
}
}
  • OrExpression
public class OrExpression implements Expression {
private Expression expr1 = null;
private Expression expr2 = null; public OrExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
} @Override
public boolean interpret(String context) {
return expr1.interpret(context) || expr2.interpret(context);
}
}
  • AndExpression
public class AndExpression implements Expression {
private Expression expr1 = null;
private Expression expr2 = null; public AndExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
} @Override
public boolean interpret(String context) {
return expr1.interpret(context) && expr2.interpret(context);
}
}

Client : InterpreterPatternDemo

  • InterpreterPatternDemo : 使用 Expression 类来创建规则,并解析它们。
public class InterpreterPatternDemo {
//规则:Robert 和 John 是男性
public static Expression getMaleExpression(){
Expression robert = new TerminalExpression("Robert");
Expression john = new TerminalExpression("John");
return new OrExpression(robert, john);
} //规则:Julie 是一个已婚的女性
public static Expression getMarriedWomanExpression(){
Expression julie = new TerminalExpression("Julie");
Expression married = new TerminalExpression("Married");
return new AndExpression(julie, married);
} public static void main(String[] args) {
Expression isMale = getMaleExpression();
Expression isMarriedWoman = getMarriedWomanExpression(); System.out.println("John is male? " + isMale.interpret("John"));
System.out.println("Julie is a married women? "
+ isMarriedWoman.interpret("Married Julie"));
}
}

out

John is male? true
Julie is a married women? true

CASE 开源 SQL 解析引擎 - Apche Calcite

  • 推荐文献

CASE 开源语法分析工具 - Antlr

  • 推荐文献

Y 推荐文献

X 参考文献

[设计模式/Java] 设计模式之解释器模式【27】的更多相关文章

  1. Java设计模式(17)解释器模式(Interpreter模式)

    Interpreter定义:定义语言的文法,并且建立一个解释器来解释该语言中的句子. Interpreter似乎使用面不是很广,它描述了一个语言解释器是如何构成的,在实际应用中,我们可能很少去构造一个 ...

  2. C#设计模式之二十三解释器模式(Interpreter Pattern)【行为型】

    一.引言   今天我们开始讲"行为型"设计模式的第十一个模式,也是面向对象设计模式的最后一个模式,先要说明一下,其实这个模式不是最后一个模式(按Gof的排序来讲),为什么把它放在最 ...

  3. 设计模式15:Interpreter 解释器模式(行为型模式)

    Interpreter 解释器模式(行为型模式) 动机(Motivation) 在软件构建过程中,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变 ...

  4. 设计模式课程 设计模式精讲 20-2 解释器模式coding

    1 代码演练 1.1 代码演练1(解释器模式coding) 1.2 代码演练如何应用了解释器模式 1 代码演练 1.1 代码演练1(解释器模式coding)(该案例运用了栈的先进先出的特性) 需求: ...

  5. 【设计模式 - 15】之解释器模式(Interpreter)

    1      模式简介 解释器模式允许我们自定义一种语言,并定义一个这种语言的解释器,这个解释器用来解释语言中的句子.由于这种模式主要用于编译器的编写,因此在日常应用中不是很常用. 如果一种特定类型的 ...

  6. 设计模式のInterpreter Patern(解释器模式)----行为模式

    一.问题产生背景 有一句话“小明和小龙是好朋友”,我想分析其中谁是人,我想分析他们的关系等多种需求,那么我们应该如何处理,如果为每一个关系都进行判断?显然不合适,我们可以将二者的关系进行抽象处理,然后 ...

  7. Head First设计模式——蝇量和解释器模式

    蝇量 蝇量模式:如果让某个类的一个实例能用来提供许多“虚拟实例”,就使用蝇量模式. 在一个设计房子的平台中,周围要加上一些树,树有一个坐标XY坐标位置,而且可以根据树的年龄动态将自己绘制出来.如果我们 ...

  8. Unity设计模式+Java设计模式,讲解+案例+PPT,一次性学会设计模式,拥抱高薪!

    一个程序员对设计模式的理解:“不懂”为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开一把锁的模式, ...

  9. OOP设计模式[JAVA]——03职责链模式

    职责链模式 Responsibility of Chain 在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求 ...

  10. 简单工厂设计模式--Java设计模式(一)

    一 概念: 简单工厂模式就是通过一个工厂类根据参数动态创建对应的类. 二 案例 我们以汽车作为例子,在现实生活中汽车只是一个抽象的产品,其中有很多类型的汽车才是具体产品,如奔驰.宝马.保时捷等等(当然 ...

随机推荐

  1. DBeaver出现“Public Key Retrieval is not allowed”错误的解决办法

    1.问题描述 我们在使用DBeaver连接MySql的时候,可能会出现"Public Key Retrieval is not allowed"的错误提示,如下图所示: 2.解决办 ...

  2. .Net Core WebAPI部署多服务器配置Nginx负载均衡

    下载Nginx包: https://nginx.org/en/download.html 首先下载Nginx包 注意:下载路径必须为英文,不能到中文: 启动Nginx: 打开刚刚下载的Nginx包,然 ...

  3. 燕千云ITSM已支持DeepSeek对接!AI能力持续升级

    春节期间,DeepSeek火爆全网,引发热议,作为国产AI大模型的黑马,DeepSeek凭借独特的训练方法.先进的模型架构和强大的联网推理能力,正不断拓展AI技术的应用边界.其"快思考&qu ...

  4. IAP升级(STM32)

    IAP升级(STM32) IAP作用简述:将要升级的程序bin文件通过串口发送给STM32,STM32接收后存储到FLASH或者SRAM,用户通过事件(按键等)触发(也可延时自动触发)后将升级 文件夹 ...

  5. 大数据之路Week08_day06 (Zookeeper搭建)

    Zookeeper集群搭建 在本文中Zookeeper节点个数(奇数)为3个.Zookeeper默认对外提供服务的端口号2181 .Zookeeper集群内部3个节点之间通信默认使用2888:3888 ...

  6. php获取详细访客信息,获取访客IP,IP归属地,访问时间,操作系统,浏览器,移动端/PC端,环境语言,访问URL等信息

    问题描述:需要获取访客访问网站信息 1.代码示例与说明: <?php header("Content-Type: text/html; charset=utf-8");    ...

  7. python 二级 语言基本元素笔记-字符串

    l='12345' 1.递增顺序: 正向递增从0开始 负向从[-1]开始,l[1]=2,l[-1]=5 2.切片操作:左开右闭,l[2:5]=3,4 3.导入库,引入 库名.函数名 input函数 输 ...

  8. Ubuntu Nvidia driver驱动安装及卸载

    前言 当前英伟达下载的驱动不再是 .run 的 shell文件,所以有了新的文档,如下 Ubuntu Nvidia driver驱动安装(新) 当然如果你有 shell 文件,也可以继续使用本文档安装 ...

  9. vue 格式化时间戳

    前言 有时候我们需要前端处理后端传过来的时间戳进行格式化为日期. Html部分 template中这样使用,需要处理的字段名,再加上过滤器方法 <el-table-column label=&q ...

  10. centos操作collection

    Centos修改IP地址 https://blog.csdn.net/weixin_45193791/article/details/124646170 Centos打开.修改.保存文件 https: ...