Java设计模式-解释器模式Interpreter

news2024/9/23 15:32:34

在这里插入图片描述

介绍

  1. 在编译原理中,一个算术表达式通过词法分析器形成词法单元,而后这些词法单元再通过语法分析器构建语法
    分析树,最终形成一颗抽象的语法分析树。这里的词法分析器和语法分析器都可以看做是解释器
  2. 解释器模式(Interpreter Pattern):是指给定一个语言(表达式),定义它的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子(表达式)
  3. 应用场景
  • 应用可以将一个需要解释执行的语言中的句子表示为一个抽象语法树
  • 一些重复出现的问题可以用一种简单的语言来表达
  • 一个简单语法需要解释的场景
  1. 这样的例子还有,比如编译器、运算表达式计算、正则表达式、机器人等

原理类图

在这里插入图片描述

  • 对原理类图的说明-即(解释器模式的角色及职责):
  1. Context: 是环境角色,含有解释器之外的全局信息. 2) AbstractExpression: 抽象表达式, 声明一个抽象的解释操作,这个方法为抽象语法树中所有的节点所共享
  2. TerminalExpression: 为终结符表达式, 实现与文法中的终结符相关的解释操作
  3. NonTermialExpression: 为非终结符表达式,为文法中的非终结符实现解释操作. 5) 说明: 输入 Context he TerminalExpression 信息通过 Client 输入即可

实战案例

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

InterpreterPatternDemo,我们的演示类使用 Expression 类创建规则和演示表达式的解析。
在这里插入图片描述

代码实现

public interface Expression {
   public boolean interpret(String context);
}
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;
   }
}
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);
   }
}
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);
   }
}
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"));
   }
}
  • 输出:
John is male? true
Julie is a married women? true

源码剖析

  1. Spring 框架中 SpelExpressionParser 就使用到解释器模式
  2. 代码分析+Debug 源码:
    在这里插入图片描述
    在这里插入图片描述

注意事项

  1. 当有一个语言需要解释执行,可将该语言中的句子表示为一个抽象语法树,就可以考虑使用解释器模式,让程序具有良好的扩展性。
  2. 应用场景:编译器、运算表达式计算、正则表达式、机器人等。
  3. 使用解释器可能带来的问题:解释器模式会引起类膨胀、解释器模式采用递归调用方法,将会导致调试非常复杂、效率可能降低。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/181646.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux操作系统使用git提交代码

引言: 北京时间 2023/1/27/9:50,今天的起床时间9:05,可以看出我们是提前了一些些,但是不是我的功劳,当然也不是我的闹钟的功劳,毕竟我的闹钟是8:20和8:50的,因为我亲爱的老妈……懂…

threejs相机控件使用记录

文章目录前言控件列表轨迹球控制器(TrackBallControls)第一人称控制器(FirstPersonControls)飞行控制器(FlyControls)轨道控制器(OrbitControls)总结前言 threejs提供了很多摄像机控…

mixamo和ue小白人映射关系以及让mixamo绑定的人物在场景中运动的多种方法实践...

ue中的root->Hips ue中 ik_foot_l ik_foot_r下面有foot_r 在mixamo下面leftfoot对应ik_foot_l 但是foot_l 只能给他对应leftToeBase 了 image.pngspline 盆骨对应pelvis 在绑定控制中进行修改即可. image.png方法一 拷贝动画蓝图 [本人原创方法] 此方法毕竟操蛋,虽然完美兼容…

Linux驱动开发基础__休眠与唤醒

目录 1 适用场景 2 内核函数 2.1 休眠函数 2.2 唤醒函数 3 驱动框架 4 编程 4.1 gpio_key_drv.c 4.2 button_test.c 4.3 Makefile 1 适用场景 在前面引入中断时,我们曾经举过一个例子: 妈妈怎么知道卧室里小孩醒了? 休眠-唤醒&…

pytorch深度学习案例(一)——手写数学符号识别

文章目录前言简介数据集项目结构utils模块dataLoadermodelsplotShowtrain模块predict模块下载地址前言 在前面的两篇文章中我们介绍了现代计算机视觉中常见的结构化和非结构化的CNN模型,本篇我们将使用这些CNN模型在手写数学符号数据集上进行识别。 CNN模型的介绍请…

2022回顾

2022年回顾 前言 新年和亲朋好友的相聚差不多接近尾声,假期也所剩无几,开始静下心来写作,回顾一下我的2022年,看下自己去年 做得好的和不足,展望下2023,开始新一年的生活。(因为是公历2023年…

Grafana 系列文章(一):基于 Grafana 的全栈可观察性 Demo

📚️Reference: https://github.com/grafana/intro-to-mlt 这是关于 Grafana 中可观察性的三个支柱的一系列演讲的配套资源库。 它以一个自我封闭的 Docker 沙盒的形式出现,包括在本地机器上运行和实验所提供的服务所需的所有组件。 Grafana 全栈可观察…

剑指 Offer 第9天 第10天

目录 剑指 Offer 42. 连续子数组的最大和 剑指 Offer 47. 礼物的最大价值 剑指 Offer 46. 把数字翻译成字符串 剑指 Offer 48. 最长不含重复字符的子字符串 剑指 Offer 42. 连续子数组的最大和 输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所…

Python self用法详解

在定义类的过程中,无论是显式创建类的构造方法,还是向类中添加实例方法,都要求将 self 参数作为方法的第一个参数。例如,定义一个 Person 类:class Person: def__init__(self): print("正在执行构造方法") #…

大数据项目---电商数仓(三)

目录 1.即席查询_Presto概述 2.即席查询_Presto_Server的部署 3.即席查询_Presto_Server启动 4.即席查询_命令行客户端说明 5.即席查询_LZO说明 6.即席查询_Presto_web端口 ​编辑 7.即席查询_Presto使用注意事项/优化 8.即席查询_Kylin简介 9.即席查询_前置概念 10.即…

数据库系统结构、数据库系统的组成

文章目录一、数据库系统的三级模式结构1.模式(逻辑模式)2.外模式(子模式、用户模式)3.内模式(存储模式)二、数据库的二级映像功能1.外模式/模式映像2.模式/内模式映像3.实际应用三、数据库系统的组成---硬件…

安卓性能优化之内存优化

Java对象生命周期: 创建:为对象分配内存空间,构造对象应用:此时 对象至少被一个强引用持有不可见:未被任何强引用持有,进行可达性分析不可达:可达性分析为不可达,进入下一阶段收集&…

notes

等差:,求 解:、 ,则 解: x系数y系数1412 由 得分母 ;则分子为, 解:令 已知两边及夹角,可图解 解析几何条件转化 1.平行四边形条件的转化几何性质代数实现(1)对边平行斜…

【IoT】创业:如何找到可以主导的创业市场?

如果你想开始创业,开启一段不一样的旅程,那么你首先要做的就是选赛道! 如何选择你的赛道、你的第一个市场呢? 换句话说就是,你如何选择自己的利基市场。 最大的市场,同时,它的需求范围也最广…

全国地级市1999—2020年污染物排放和环境治理相关指标(废水\废气\粉尘等)

工业废水、工业粉尘等污染物是影响居住环境的重要因素,也是在各项研究中常用的数据!之前我们基于历年的《中国城市统计年鉴》整理了1999—2020年的人口相关数据和用地相关数据(可查看之前推送的文章)。在《中国城市统计年鉴》中也…

欧拉回路(模板+外加一些优化)

给定一张图,请你找出欧拉回路,即在图中找一个环使得每条边都在环上出现恰好一次。 输入格式 第一行包含一个整数t, t∈ {1,2},如果t 1,表示所给图为无向图,如果t2,表示所给图为有向图。 第二行包含两个整数…

【MySQL】日志

https://www.cnblogs.com/myseries/p/10728533.html 在 MySQL 中,有多种不同的日志,包括错误日志、二进制日志、查询日志和慢查询日志,这些日志发挥着不同的作用。另外还有redo日志、undo日志和relay日志。 错误日志 错误日志是 MySQL 中最…

测试篇(四):测试用例的分类、按测试对象划分、按是否查看代码划分、你平时哪种测试方法用的多?、按照开发阶段划分

目录一、按测试对象划分1.1 界面测试1.2 可靠性测试1.3 容测性测试1.4 文档测试1.5 兼容性测试1.6 易用性测试1.7 安装卸载测试1.8 安全测试1.9 性能测试1.10 内存泄露测试1.11 弱网测试二、按是否查看代码划分2.1 黑盒测试2.2 白盒测试2.4 灰盒测试三、面试题:你平…

AcWing 327. 玉米田(状态压缩DP)

AcWing 327. 玉米田(状态压缩DP)一、问题二、分析1、思路2、状态表示3、状态转移4、循环设计5、初末状态三、代码一、问题 二、分析 1、思路 这道题与之前所讲解的AcWing 1064. 小国王(状态压缩DP)非常相似,所以如果…

ARM uboot 的源码目录分析

一、uboot的源码目录分析1 1、九鼎官方 uboot 和三星原版 uboot 对比 (1) 以九鼎官方的 uboot 为蓝本来学习的,以三星官方的这份为对照。 (2) 不同版本的 uboot 或者同一版本不同人移植的 uboot,可能目录结构和文件内容都有所不同。将来大家懂了后也可…