【设计模式深度剖析】【11】【行为型】【解释器模式】| 以算术表达式求值为例加深理解
👈️上一篇:状态模式
设计模式-专栏👈️
文章目录
- 解释器模式
- 定义
- 英文原话
- 直译
- 解释器模式中的角色
- 1. 抽象表达式(AbstractExpression)
- 2. 终端表达式(TerminalExpression)
- 3. 非终端表达式(NonterminalExpression)
- 4. 环境(Context)
- 5. 客户端(Client)
- 代码示例:算术表达式求值
- 类图
- 代码
- 解释器模式的应用
- 解释器模式的优点
- 解释器模式的缺点
- 解释器模式的使用场景
解释器模式
解释器模式(Interpreter Pattern)
解释器模式就像是一个翻译官,它可以将一种语言(比如我们编写的程序代码或配置文件)翻译成另一种语言(比如计算机可以理解的机器代码)。这种翻译官非常灵活,可以轻松地处理各种复杂的语法和表达式。但是,如果语法规则太多太复杂,翻译官可能会感到头疼,因为他需要记住很多规则,这会让他的工作变得困难。所以,当我们要使用解释器模式时,最好确保语言的文法规则相对简单,这样可以提高翻译官的工作效率。
当有一个语言需要解释执行,并且你可以将该语言中的句子表示为一个抽象语法树(AST)时,可使用解释器模式。
定义
英文原话
The Interpreter pattern specifies a representation for a grammar along with an interpreter that uses the representation to interpret sentences in the grammar.
直译
解释器模式定义了一个文法的表示以及一个解释器,该解释器使用该表示来解释文法中的句子。
解释器模式中的角色
1. 抽象表达式(AbstractExpression)
声明一个抽象的解释操作,这个接口为抽象语法树(AST)中所有节点所共享,为所有的终端表达式和非终端表达式声明一个解释操作。
2. 终端表达式(TerminalExpression)
实现了抽象表达式的解释操作,对应文法中的终结符,即不可再分的表达式。
3. 非终端表达式(NonterminalExpression)
实现了抽象表达式的解释操作,并包含一个或多个对抽象表达式的引用,用于组合文法规则。
4. 环境(Context)
包含解释器之外的一些全局信息,一般是用来传递参数给解释器的。
5. 客户端(Client)
构建抽象语法树(AST)的结构,并调用解释操作来执行相应的功能。
代码示例:算术表达式求值
类图

代码
以下是一个简单的 Java 示例,它展示了如何使用解释器模式来解析和计算算术表达式(只包括加法和乘法):
package com.polaris.designpattern.list3.behavioral.pattern11.interpreter.demo1;// 抽象表达式
interface Expression {int interpret(Context context);
}// 环境(本例中环境较简单,没有使用)
class Context {// 这里可以添加一些全局信息,如变量值等
}// 终端表达式(数字)
class NumberExpression implements Expression {private int value;public NumberExpression(int value) {this.value = value;}@Overridepublic int interpret(Context context) {return value;}
}// 非终端表达式(加法)
class AddExpression implements Expression {private Expression left;private Expression right;public AddExpression(Expression left, Expression right) {this.left = left;this.right = right;}@Overridepublic int interpret(Context context) {return left.interpret(context) + right.interpret(context);}
}// 非终端表达式(乘法)
class MultiplyExpression implements Expression {private Expression left;private Expression right;public MultiplyExpression(Expression left, Expression right) {this.left = left;this.right = right;}@Overridepublic int interpret(Context context) {return left.interpret(context) * right.interpret(context);}
}// 客户端
public class Client {public static void main(String[] args) {// 构造表达式:(5+10)*2Expression five = new NumberExpression(5);Expression ten = new NumberExpression(10);Expression sum = new AddExpression(five, ten);Expression product = new MultiplyExpression(sum, new NumberExpression(2));// 本例中未使用Context context = new Context();int result = product.interpret(context);// 输出 30System.out.println("Result: " + result);}
}
/* Output:
Result: 30
*///~
在这个例子中,我们定义了一个
Expression接口作为抽象表达式,NumberExpression作为终端表达式,表示一个具体的数字值。我们还定义了两个非终端表达式AddExpression和MultiplyExpression,分别表示加法和乘法操作。客户端负责构建抽象语法树(AST)并调用interpret方法来计算表达式的值。注意,在这个例子中我们没有使用Context类,因为它在这个简单的示例中并不必要。
解释器模式的应用
解释器模式主要应用于需要处理复杂语法和表达式的场合。以下是一些具体的应用示例:
- 表达式求值器:在处理复杂的数学表达式或逻辑表达式时,解释器模式非常有用。开发人员可以定义各种表达式类型的解释器(如加法、减法、乘法、逻辑与、逻辑或等),然后使用这些解释器来解析和计算表达式。
- 配置文件解析:当应用程序需要从配置文件中读取参数和设置时,解释器模式可以用来解析配置文件的内容。这可以确保配置文件的格式正确,并且使得应用程序能够轻松地读取和解析配置文件。
- 编译器设计:解释器模式在编译器设计中非常常见。编译器需要将源代码(一种人类可读的编程语言)转换为机器代码(计算机可以执行的指令)。解释器模式允许开发人员为每种语言结构定义解释器,这些解释器可以逐一解析源代码,并生成相应的机器代码。
解释器模式的优点
- 易于改变和扩展文法:由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承等机制来改变或扩展文法。
- 实现简单语言方便:每一条文法规则都可以表示为一个类,因此可以方便地实现一个简单的语言。
- 增加新的解释表达式方便:如果用户需要增加新的解释表达式,只需要对应增加一个新的终结符表达式或非终结符表达式类,原有表达式类代码无须修改,符合“开闭原则”。
解释器模式的缺点
- 对于复杂文法难以维护:如果一个语言包含太多文法规则,类的个数将会急剧增加,导致系统难以管理和维护。
- 执行效率较低:由于在解释器模式中使用了大量的循环和递归调用,因此在解释较为复杂的句子时其速度很慢,而且代码的调试过程也比较麻烦。
解释器模式的使用场景
- 特定类型问题发生频率足够高:当某个特定类型的问题在系统中频繁出现时,使用解释器模式可以提高代码的可重用性和可维护性。
- 语言文法较为简单:当需要解释的语言的文法较为简单时,使用解释器模式可以方便地实现一个解释器。
- 执行效率不是关键问题:如果系统的性能瓶颈不在于表达式的解析速度,那么可以使用解释器模式来提高代码的可读性和可维护性。
👈️上一篇:状态模式
设计模式-专栏👈️
相关文章:
【设计模式深度剖析】【11】【行为型】【解释器模式】| 以算术表达式求值为例加深理解
👈️上一篇:状态模式 设计模式-专栏👈️ 文章目录 解释器模式定义英文原话直译 解释器模式中的角色1. 抽象表达式(AbstractExpression)2. 终端表达式(TerminalExpression)3. 非终端表达式(Non…...
MySQL8,Navicat能登陆成功,密码却忘记了
执行成功的图: 以下为步骤:本文一共8个简单步骤。 环境:mysql8、window10、navicat11 1、打开本地电脑window10的命令窗(俗称黑窗口),windowR 2、输入regegit,回车,打开注册表 3、…...
游戏中的寻路算法研究
1)Unity NavMesh研究 思考:毫无疑问,unity中自带的navmesh寻路是比较健全的,无奈在服务器中无法使用,这样子我们没办法做怪的导航,但是可以先体验下都有哪些api,并且可以可视化的看效果。 1)打开导航网格…...
【AWS SMB】关于AWS 中小型企业 (SMB) 能力介绍及注意事项
文章目录 前言一、什么是 SMB?📢二、如何识别中小企业的需求三、中小企业营销活动的类型四、AWS 合作伙伴可获得的其他 AWS 机会4.1 AWS IQ4.2 APN 客户参与 (ACE) 计划 前言 AWS 中小型企业 (SMB) 能力合作伙伴专注于帮助中小型…...
中年之恋:重返青春的旅程
第一章:重逢 在一个普通的周末,李明参加了一次由老同学组织的聚会,尽管他对此并不抱有太大的兴趣,但出于礼貌还是选择了出席。聚会在一家风格复古的咖啡馆里举行,暖黄色的灯光与木质的装饰让人不自觉地放缓了脚步。在…...
人工智能中的监督学习和无监督学习
欢迎来到 Papicatch的博客 目录 🍉引言 🍉监督学习 🍈基本思想 🍈具体过程 🍍数据收集 🍍数据预处理 🍍模型选择 🍍模型训练 🍍模型评估 🍍模型部署…...
深度学习500问——Chapter12:网络搭建及训练(1)
文章目录 12.1 TensorFlow 12.1.1 TensorFlow 是什么 12.1.2 TensorFlow的设计理念是什么 12.1.3 TensorFlow特点有哪些 12.1.4 TensorFlow的系统架构是怎样的 12.1.5 TensorFlow编程模型是怎样的 12.1.6 如何基于TensorFlow搭建VGG16 12.1 TensorFlow 12.1.1 TensorFlow 是什…...
HuggingFace CLI 命令全面指南
文章目录 安装与认证1.1 安装 HuggingFace Hub 库使用 pip 安装使用 conda 安装验证安装 1.2 认证与登录生成访问令牌使用访问令牌登录环境变量认证验证认证 下载文件2.1 下载单个文件安装 huggingface_hub 库认证与登录下载单个文件 2.2 下载特定版本的文件下载特定版本的文件…...
FreeRTOS源码分析
目录 1、FreeRTOS目录结构 2、核心文件 3、移植时涉及的文件 4、头文件相关 4.1 头文件目录 4.2 头文件 5、内存管理 6、入口函数 7、数据类型和编程规范 7.1 数据类型 7.2 变量名 7.3 函数名 7.4 宏的名 1、FreeRTOS目录结构 使用 STM32CubeMX 创建的 FreeRTOS 工…...
python实战:将视频内容上传到社交媒体平台
在Python中,上传视频到不同的平台可能需要使用不同的API和库。以下是一些常见的平台以及如何使用Python进行上传的示例: YouTube: 使用Google提供的YouTube Data API。 首先,你需要从Google Cloud控制台获取API密钥,并安装google-…...
【深度学习】sdwebui A1111 加速方案对比,xformers vs Flash Attention 2
文章目录 资料支撑资料结论sdwebui A1111 速度对比测试sdxlxformers 用contorlnet sdxlsdpa(--opt-sdp-no-mem-attention) 用contorlnet sdxlsdpa(--opt-sdp-attention) 用contorlnet sdxl不用xformers或者sdpa ,用contorlnet sdxl不用xformers或者sdpa …...
5分钟了解单元测试
🍅 视频学习:文末有免费的配套视频可观看 🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 一、什么是单元测试? 单元测试是指,对软件中的最小可测试单元在与程序其…...
VSCode之C/C++插件之宏定义导致颜色变暗
这是因为该宏没有定义或者定义在makefile文件中导致无法被插件识别到,导致误判了 索性将该机制去了,显示也会好看些,如下将C_Cpp下的Dim Inactive Regions勾去了 显示效果会好很多。...
自然语言处理概述
目录 1.概述 2.背景 3.作用 4.优缺点 4.1.优点 4.2.缺点 5.应用场景 5.1.十个应用场景 5.2.文本分类 5.2.1.一般流程 5.2.2.示例 6.使用示例 7.总结 1.概述 自然语言处理(NLP)是计算机科学、人工智能和语言学的交叉领域,旨在实…...
用Rust和Pingora轻松构建超越Nginx的高效负载均衡器
目录 什么是Pingora?实现过程 初始化项目编写负载均衡器代码代码解析部署 总结 1. 什么是Pingora? Pingora 是一个高性能的 Rust 库,用于构建可负载均衡器的代理服务器,它的诞生是为了弥补 Nginx 存在的缺陷。 Pingora 提供了…...
华为云与AWS负载均衡服务深度对比:性能、成本与可用性
随着云计算的迅速发展,企业对于云服务提供商的选择变得越来越关键。在选择云服务提供商时,负载均衡服务是企业关注的重点之一。我们九河云将深入比较两大知名云服务提供商华为云和AWS的负载均衡服务,从性能、成本和可用性等方面进行对比。 AW…...
Vue65-组件之间的传值
1、收数据 2、传数据 3、批量的数据替换 若是info里面有四个数据,传过来的dataObj里面有三个数据,则info里面也只有三个数据了 解决方式: 该写法还有一个优势:传参的时候,顺序可以随意!...
Java零基础之多线程篇:线程生命周期
哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一…...
技术差异,应用场景;虚拟机可以当作云服务器吗
虚拟机和云服务器是现在市面上常见的两种计算资源提供方式,很多人把这两者看成可以相互转换或者替代的物品,实则不然,这两种资源提供方式有许多相似之处,但是也有不少区别,一篇文章教你识别两者的技术差异,…...
Qt Quick 教程(一)
文章目录 1.Qt Quick2.QML3.Day01 案例main.qml退出按钮,基于上面代码添加 4.使用Qt Design StudioQt Design Studio简介Qt Design Studio工具使用版本信息 1.Qt Quick Qt Quick 是一种现代的用户界面技术,将声明性用户界面设计和命令性编程逻辑分开。 …...
Proteus仿真C51单片机:用汇编实现一个简易的脉冲计数器(附完整代码和电路图)
Proteus仿真C51单片机:用汇编实现一个简易的脉冲计数器(附完整代码和电路图) 当你第一次接触单片机编程时,可能会被各种寄存器、中断和端口配置搞得晕头转向。今天,我们就用一个实实在在的脉冲计数器项目,带…...
I3C协议学习总结
I3C可以使用推挽式,节省功耗,速度更快SDR 单数据传输速率, SCL时钟频率可达到12.5MHz所有符合I3C标准的设备都必须要拥有一个总线特性寄存器1. I3C 协议模式概览 (Section 5)文档首先列出了 I3C 支持的几种主要通信模式:SDR (Sing…...
华为 eNSP 实战:SSH 密钥认证配置与安全加固指南
1. 为什么选择SSH密钥认证而非密码? 在华为eNSP模拟的企业网络环境中,传统的SSH密码认证虽然比Telnet安全,但依然存在被暴力破解的风险。我曾在实际项目中发现,使用弱密码的设备在暴露公网后,平均每天会遭受上千次登录…...
解锁Blender操作可视化:6大核心价值与7个实战技巧提升300%教程质量
解锁Blender操作可视化:6大核心价值与7个实战技巧提升300%教程质量 【免费下载链接】Screencast-Keys Blender Add-on: Screencast Keys 项目地址: https://gitcode.com/gh_mirrors/sc/Screencast-Keys 在数字创作领域,操作可视化是连接创作者与观…...
OpenClaw节日应用:GLM-4.7-Flash驱动春节祝福邮件批量定制与发送
OpenClaw节日应用:GLM-4.7-Flash驱动春节祝福邮件批量定制与发送 1. 为什么需要自动化节日邮件? 每年春节前,我都会陷入同样的困境——需要给200多位合作伙伴发送祝福邮件。手动操作意味着:反复复制粘贴内容、检查收件人姓名、调…...
YOLOv9镜像实测:无需配置环境,快速实现目标检测全流程
YOLOv9镜像实测:无需配置环境,快速实现目标检测全流程 1. 开箱即用的YOLOv9体验 对于目标检测开发者来说,最头疼的往往不是算法本身,而是环境配置这个"拦路虎"。不同版本的CUDA、PyTorch、Python之间的兼容性问题&…...
Qwen2.5-VL-7B-Instruct部署案例:律所合同图像关键条款高亮+法律依据自动关联
Qwen2.5-VL-7B-Instruct部署案例:律所合同图像关键条款高亮法律依据自动关联 1. 这不是普通OCR,是懂法的视觉助手 你有没有遇到过这样的场景:律所助理收到客户发来的扫描版PDF合同,需要在30分钟内标出违约责任、管辖法院、保密义…...
红日靶场(二)phpstudy服务异常排查与修复指南
1. phpstudy服务异常排查思路 遇到phpstudy服务启动失败时,很多新手会直接重装软件,其实80%的问题通过系统化排查都能解决。我处理过上百个红日靶场环境,总结出这套黄金排查法则: 首先确认报错类型,常见的三种情况&…...
告别硬编码!Activiti7流程变量与监听器实战:动态分配审批人与业务数据流转
Activiti7流程变量与监听器实战:动态审批人分配与业务数据流转 在业务流程管理(BPM)领域,硬编码审批人始终是系统灵活性的主要障碍。当组织架构调整或审批规则变化时,传统方案往往需要重新部署流程定义。本文将深入探…...
别再只盯着find提权了!盘点Linux下5种更隐蔽的权限维持姿势与排查手册
超越find提权:Linux系统下5种高阶权限维持技术与深度排查指南 当攻击者成功获取Linux系统权限后,权限维持(Persistence)往往成为攻防对抗的核心战场。传统安全培训常聚焦于SUID提权等基础手段,但真实APT攻击中…...
