小谈设计模式(28)—解释器模式
小谈设计模式(28)—解释器模式
- 专栏介绍
- 专栏地址
- 专栏介绍
- 解释器模式
- 角色分析
- 抽象表达式(Abstract Expression)
- 终结符表达式(Terminal Expression)
- 非终结符表达式(Non-terminal Expression)
- 上下文(Context)
- 客户端(Client)
- 工作原理
- 1
- 2
- 3
- 优缺点分析
- 优点
- 可扩展性
- 易于实现语法规则
- 易于修改和维护
- 缺点
- 复杂性
- 性能问题
- Java程序示例
- 首先,我们定义抽象表达式接口 Expression,其中包含一个解释方法 interpret:
- 然后,我们实现具体的终结符表达式 NumberExpression,它表示一个数字:
- 接下来,我们实现具体的非终结符表达式 AddExpression,它表示两个表达式的相加操作:
- 接下来,我们定义上下文类 Context,用于存储解释器需要的全局信息:
- 最后,我们可以在客户端中使用解释器模式:
- 分析
- 总结
专栏介绍
专栏地址
http://t.csdnimg.cn/VpriY
专栏介绍
主要对目前市面上常见的23种设计模式进行逐一分析和总结,希望有兴趣的小伙伴们可以看一下,会持续更新的。希望各位可以监督我,我们一起学习进步,加油,各位。
解释器模式
解释器模式是一种行为型设计模式,它提供了一种解释一个语言的方式,用于解析和执行特定的文法规则。该模式将一个语言表示为一个解释器,该解释器可以解释语言中的表达式,从而实现特定的行为。
角色分析
抽象表达式(Abstract Expression)
定义了一个抽象的解释操作,所有的具体表达式都继承自该抽象类。
终结符表达式(Terminal Expression)
表示语法中的终结符,即不再进行解释的表达式。
非终结符表达式(Non-terminal Expression)
表示语法中的非终结符,该表达式可以通过递归调用其他表达式来解释。
上下文(Context)
包含解释器需要的一些全局信息。
客户端(Client)
创建和配置解释器,然后调用解释器的解释方法来解释语言中的表达式。
工作原理
1
客户端创建和配置解释器,并将需要解释的语言表达式传递给解释器。
2
解释器根据语法规则,将表达式解释成相应的抽象语法树。
3
客户端调用解释器的解释方法,解释器根据抽象语法树递归地解释表达式,最终得到结果。
优缺点分析
优点
可扩展性
通过增加新的表达式类,可以轻松扩展语言的语法规则。
易于实现语法规则
解释器模式将每个语法规则都封装在一个表达式类中,使得每个规则的实现都相对简单。
易于修改和维护
由于解释器模式将语法规则和表达式分离,因此可以独立地修改和维护每个表达式类。
缺点
复杂性
随着语法规则的增加,解释器模式的复杂性也会增加,维护和理解整个解释器系统可能会变得困难。
性能问题
由于解释器模式需要递归地解释表达式,可能会导致性能问题,特别是处理大型表达式时。
Java程序示例
首先,我们定义抽象表达式接口 Expression,其中包含一个解释方法 interpret:
public interface Expression {int interpret(Context context);
}
然后,我们实现具体的终结符表达式 NumberExpression,它表示一个数字:
public class NumberExpression implements Expression {private int number;public NumberExpression(int number) {this.number = number;}@Overridepublic int interpret(Context context) {return number;}
}
接下来,我们实现具体的非终结符表达式 AddExpression,它表示两个表达式的相加操作:
public class AddExpression implements Expression {private Expression leftExpression;private Expression rightExpression;public AddExpression(Expression leftExpression, Expression rightExpression) {this.leftExpression = leftExpression;this.rightExpression = rightExpression;}@Overridepublic int interpret(Context context) {int leftValue = leftExpression.interpret(context);int rightValue = rightExpression.interpret(context);return leftValue + rightValue;}
}
接下来,我们定义上下文类 Context,用于存储解释器需要的全局信息:
public class Context {private Map<String, Integer> variables;public Context() {variables = new HashMap<>();}public void setVariable(String name, int value) {variables.put(name, value);}public int getVariable(String name) {return variables.get(name);}
}
最后,我们可以在客户端中使用解释器模式:
public class Client {public static void main(String[] args) {// 创建上下文Context context = new Context();context.setVariable("x", 10);context.setVariable("y", 5);// 创建表达式Expression expression = new AddExpression(new NumberExpression(context.getVariable("x")),new NumberExpression(context.getVariable("y")));// 解释表达式int result = expression.interpret(context);System.out.println("Result: " + result); // 输出结果: Result: 15}
}
分析
在上面的示例中,我们创建了一个上下文对象,并设置了两个变量 x 和 y 的值。然后,我们创建了一个表达式对象,该表达式对象表示将变量 x 和 y 相加的操作。最后,我们调用表达式的解释方法,传入上下文对象,得到最终的结果并输出。
总结
解释器模式是一种用于解释和执行特定语言的设计模式。它通过将语言表示为一个解释器,并使用抽象语法树来解释表达式,实现了特定的行为。尽管存在一些缺点,但解释器模式在某些特定场景下仍然是一个有用的设计模式。
相关文章:

小谈设计模式(28)—解释器模式
小谈设计模式(28)—解释器模式 专栏介绍专栏地址专栏介绍 解释器模式角色分析抽象表达式(Abstract Expression)终结符表达式(Terminal Expression)非终结符表达式(Non-terminal Expression&…...
Access denied for user ‘root‘@‘xxx‘ (using password: YES)
Access denied for user rootxxx (using password: YES) 这表示MySQL服务端拒绝来自xxx主机的root用户登录,尽管我检查了一下,root的用户名和密码都没错,还是拒绝。 解决方案: select user,host from mysql.user; 执行发现&am…...
对象与成员函数指针 function+bind
functionbind的理解 function模板类的构造函数,把对象与成员函数绑定,重载了(),利用对象调用成员函数 bind模板函数,把对象与成员函数绑定,返回function对象,成员函数传参代码链接点…...

如何在 PyTorch 中冻结模型权重以进行迁移学习:分步教程
一、说明 迁移学习是一种机器学习技术,其中预先训练的模型适用于新的但类似的问题。迁移学习的关键步骤之一是能够冻结预训练模型的层,以便在训练期间仅更新网络的某些部分。当您想要保留预训练模型已经学习的特征时,冻结至关重要。在本教程中…...

代码随想录算法训练营第六十二、六十三天 | 单调栈 part 2 | 503.下一个更大元素II 、42. 接雨水、84.柱状图中最大的矩形
目录 503.下一个更大元素II思路代码 42. 接雨水思路一 双指针思路二 单调栈代码 84.柱状图中最大的矩形思路一 双指针思路二 单调栈代码 503.下一个更大元素II Leetcode 思路 将数组乘2来遍历即可,就是加长版的每日温度。 但是处理起来会有细节,如果…...

c#设计模式-行为型模式 之 迭代器模式
🚀简介 提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。 迭代器模式主要包含以下角色: 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合元素以及创建迭代器对象的接口…...

SSM整合RabbitMQ,Spring4.x整合RabbitMQ
SSM整合RabbitMQ目录 前言版本实现目录参考pom.xml依赖rabbitmq.properties配置文件spring-rabbitmq.xmlspring-mvc.xml或applicationContext.xmlrabbitmq目录下MessageConsumer.javaMessageConsumer2.javaMessageProducer.javaMessageConstant.java 测试调用 扩展消息重发方式…...

【2023研电赛】商业计划书赛道上海市一等奖:基于双矢量优化谐波预测控制的MMC-PET光伏储能系统
该作品参与极术社区组织的2023研电赛作品征集活动,欢迎同学们投稿,获取作品传播推广,并有丰富礼品哦~ 团队介绍 参赛单位:上海理工大学 参赛队伍:Dream explorers 参赛队员:吕哲 李天皓 赵安杰 项目意义…...

minio桶命名规则
一、背景 今天做项目需要上传图片到minio,上传失败,查看错误是桶未创建成功。 minio桶的创建具有自己的命名规则,不符合则无法创建。 二、命名规则 1、存储桶名称的长度必须介于 3(最小)到 63(最大&…...

【教学类-35-04】学号+姓名+班级(中3班)学号字帖(A4竖版2份 竖版长条)
图片展示: 背景需求: 2022年9-2023年1月我去过小3班带班,但是没有在这个班级投放过学具,本周五是我在本学期第一次带中3班,所以提供了一套学号描字帖。先让我把孩子的名字和脸混个眼熟。 之前试过一页两套名字的纸张切割方法有:…...

什么叫AI自动直播?
AI自动直播是一种使用人工智能技术进行自动直播的程序或系统。 它可以自动录制视频,并在直播平台上进行展示,以吸引观众并提高品牌知名度。AI自动直播通常需要使用特定的软件或平台来实现,并且需要具备一定的编程和人工智能知识。 AI自动直…...

LLaMA Adapter和LLaMA Adapter V2
LLaMA Adapter论文地址: https://arxiv.org/pdf/2303.16199.pdf LLaMA Adapter V2论文地址: https://arxiv.org/pdf/2304.15010.pdf LLaMA Adapter效果展示地址: LLaMA Adapter 双语多模态通用模型 为你写诗 - 知乎 LLaMA Adapter GitH…...

高压放大器在软体机器人领域的应用
软体机器人是一种新型机器人技术,与传统的硬体机器人有着很大的不同。软体机器人通常由柔软的材料制成,具有高度的柔韧性和灵活性,并且可以实现多种形状和动作。但是,软体机器人的发展面临很多技术挑战,其中之一就是控…...
《Linux C/C++服务器开发实践》之第4章 TCP服务器编程
《Linux C/C服务器开发实践》之第4章 TCP服务器编程 4.1 套接字的基本概念4.2 网络程序的架构4.3 IP地址的格式转换4.1.c 4.4 套接字的类型4.5 套接字地址4.5.1 通用socket地址4.5.2 专用socket地址4.5.3 获取套接字地址4.2.c 4.6 主机字节序和网络字节序4.3.c 4.7 协议族和地址…...
HCIA---静态路由扩展配置
静态的扩展配置: 1、负载均衡:当访问相同目标,具有多条开销相似路径时;可以让设备将流量拆分后延多条路径同时传输;起到带宽叠加的作用; 2、环回接口-- 创建后,可用于路由器测试TCP/IP协议组件…...

OCP Java17 SE Developers 复习题04
答案 F. Line 5 does not compile. This question is checking to see whether you are paying attention to the types. numFish is an int, and 1 is an int. Therefore, we use numeric addition and get 5. The problem is that we cant store an int in a String variab…...

spark中使用flatmap报错:TypeError: ‘int‘ object is not subscriptable
1、背景描述 菜鸟笔者在运行下面代码时发生了报错: from pyspark import SparkContextsc SparkContext("local", "apple1012")rdd sc.parallelize([[1, 2], 3, [7, 5, 6]])rdd1 rdd.flatMap(lambda x: x) print(rdd1.collect())报错描述如…...
node.js知识系列(5)-每天了解一点
目录 21. RESTful API 设计中的 HTTP 动词22. 中间件链和回调地狱23. Express.js 的 ORM 经验24. 错误处理中间件和 HTTP 状态码25. 事件循环(Event Loop)在异步编程中的作用26. Node.js 缓存机制27. Node.js 全局对象28. 性能分析和调优经验29. Express…...
Linux服务器(银河麒麟、CentOS 7+、CentOS 7+ 等)修改IP地址
打开终端或控制台,以root或具有sudo权限的用户身份登录。根据你的Linux发行版和网络管理工具的不同,相应的命令可能略有不同。使用以下命令编辑网络配置文件,例如eth0网卡的配置文件: 注意:ifcfg-eth0 可能会有不同的命…...

Mall脚手架总结(四) —— SpringBoot整合RabbitMQ实现超时订单处理
前言 在电商项目中,订单因为某种特殊情况被取消或者超时未支付都是比较常规的用户行为,而实现该功能我们就要借助消息中间件来为我们维护这么一个消息队列。在mall脚手架中选择了RabbitMQ消息中间件,接下来荔枝就会根据功能需求来梳理一下超时…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

软件工程 期末复习
瀑布模型:计划 螺旋模型:风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合:模块内部功能紧密 模块之间依赖程度小 高内聚:指的是一个模块内部的功能应该紧密相关。换句话说,一个模块应当只实现单一的功能…...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...
React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?
系列回顾: 在上一篇《React核心概念:State是什么?》中,我们学习了如何使用useState让一个组件拥有自己的内部数据(State),并通过一个计数器案例,实现了组件的自我更新。这很棒&#…...

SOC-ESP32S3部分:30-I2S音频-麦克风扬声器驱动
飞书文档https://x509p6c8to.feishu.cn/wiki/SKZzwIRH3i7lsckUOlzcuJsdnVf I2S简介 I2S(Inter-Integrated Circuit Sound)是一种用于传输数字音频数据的通信协议,广泛应用于音频设备中。 ESP32-S3 包含 2 个 I2S 外设,通过配置…...
VUE3 ref 和 useTemplateRef
使用ref来绑定和获取 页面 <headerNav ref"headerNavRef"></headerNav><div click"showRef" ref"buttonRef">refbutton</div>使用ref方法const后面的命名需要跟页面的ref值一样 const buttonRef ref(buttonRef) cons…...

[C++错误经验]case语句跳过变量初始化
标题:[C错误经验]case语句跳过变量初始化 水墨不写bug 文章目录 一、错误信息复现二、错误分析三、解决方法 一、错误信息复现 write.cc:80:14: error: jump to case label80 | case 2:| ^ write.cc:76:20: note: crosses initialization…...