西部数码网站备案/媒体网站
备忘录模式是用于保存对象在某个时刻的状态,来实现撤销操作。而解释器模式则是将文本按照定义的文法规则解析成对应的命令。
1 备忘录模式
需求:保存对象在某个时刻的状态,后面可以对该对象实行撤销操作。
1.1 备忘录模式介绍
提供一种状态恢复机制,在不破坏封装的前提下,捕获对象内部状态并在该对象之外保存这个状态。可以在以后将对象恢复到原先保存的状态。
图 备忘录模式 UML
public class MementoPattern {public static void main(String[] args) {String[] colors = {"red","blue","green","pink","black"};Button button = new Button();Random random = new Random();MementoCareTaker<ButtonMemento> careTaker = new MementoCareTaker<>();for (int i = 0; i < 10; i++) {button.setColor(colors[random.nextInt(colors.length)]);button.setPositionX(random.nextDouble());careTaker.pushMemento(button.createMemento());}button.restoreFromMemento(careTaker.getMemento(2));System.out.println(button);button.restoreFromMemento(careTaker.getMemento(3));System.out.println(button);button.restoreFromMemento(careTaker.getMemento(1));System.out.println(button);}private static class Button {private String color;private Double positionX;public String getColor() {return color;}public void setColor(String color) {this.color = color;}public Double getPositionX() {return positionX;}public void setPositionX(Double positionX) {this.positionX = positionX;}public ButtonMemento createMemento() {return new ButtonMemento(color,positionX);}public void restoreFromMemento(ButtonMemento memento) {this.color = memento.getColor();this.positionX = memento.positionX;;}@Overridepublic String toString() {return "Button{" +"color='" + color + '\'' +", positionX=" + positionX +'}';}}private static class ButtonMemento {private final String color;private final Double positionX;public ButtonMemento(String color, Double positionX) {this.color = color;this.positionX = positionX;}public String getColor() {return color;}public Double getPositionX() {return positionX;}}private static class MementoCareTaker<T> {private final Stack<T> stack = new Stack<>();public void pushMemento(T t) {stack.push(t);}public T getMemento(int num) {T t = null;while (num-- > 0 && !stack.isEmpty()) {t = stack.pop();}return t;}}}
1.2 优缺点
优点:
- 提供了一种状态恢复机制,对象可以方便地回到一个特定的历史步骤状态。
缺点:
- 需要保存不同时刻的对象状态,这将耗费许多内存等资源。
- 类的数量增多,当对象自带有变动时,对应的备忘类也需要修改。
2 解释器模式
需求:将文本按照特定的语法规则转换成计算机中特定的命令。
2.1 解释器模式介绍
定义一个语言的文法,并建立一个解释器来解释该语言中的句子。这里的“语言”是指使用特定格式和语法的代码。
图 解释器UML
这里的Context 一般用于存储解释器之外的一些全局信息,也可以省略这个类。
::= | 定义为。 |
| | 或。 |
‘{’和‘}’ | 组合。 |
* | 出现0或多次。 |
语言单位 | 语言构造成分,每一条语句所定义的字符串。 |
终结表达式 | 组成元素是最基本的语言单位,不能在进行分解。 |
非终结表达式 | 组成元素仍可以是表达式,可进一步分解。 |
图 文法规则说明
public class InterpreterPattern {/*** 语法规则:* value ::= a integer* operator ::= '+' | '-' | '*' | '/'* expression ::= value operator value | complexExpression* complexExpression ::= expression operator expression | expression operator (expression)*/public static void main(String[] args) {String[] textArr = {"1+4*3","4*5+3","(3+4)*23", "(3+24)-(23-8)", "(2-3)*(24+2*3)", "(((1+2)*(2+3)))+32"};for (int i = 0; i < textArr.length; i++) {System.out.print(textArr[i]);System.out.println("=" + new ComplexExpression().interpreter(textArr[i]));}}private static abstract class Expression {abstract int interpreter(String text);protected int compute(int leftNum,int rightNum,char opera) {switch (opera) {case '+': return leftNum + rightNum;case '-': return leftNum - rightNum;case '*': return leftNum * rightNum;case '/': return leftNum / rightNum;}return 0;}}/*** 复杂表达式*/private static class ComplexExpression extends Expression {@Overrideint interpreter(String text) {
// System.out.println("ComplexExpression:" + text);int letNum=0;int rightNum=0;char opera = ' ';Pattern pattern = Pattern.compile("[\\+\\-\\*\\/]");Matcher matcher = pattern.matcher(text);if (matcher.find()) {int start = matcher.start();opera = text.charAt(start);if (text.indexOf("(") == 0) { // 在操作符前面有括号, 先计算括号的内容int endBracketPos = findEndBracketPos(text);letNum = new ComplexExpression().interpreter(text.substring(1,endBracketPos));if (endBracketPos == text.length() -1 ) {return letNum;}opera = text.charAt(endBracketPos+1);rightNum = new ComplexExpression().interpreter(text.substring(endBracketPos+2));} else if ((opera == '*' || opera == '/') && text.charAt(start+1) != '(') { // 需要先完成左边运算boolean hasNext = matcher.find(start + 1);if (hasNext) {int pos2 = matcher.start();letNum = new ComplexExpression().interpreter(text.substring(0,pos2));opera = text.charAt(pos2);rightNum = new ComplexExpression().interpreter(text.substring(pos2+1));} else {letNum = new TerminalExpression().interpreter(text.substring(0,start));rightNum = new ComplexExpression().interpreter(text.substring(start+1));}} else {letNum = new TerminalExpression().interpreter(text.substring(0,start));rightNum = new ComplexExpression().interpreter(text.substring(start+1));}return compute(letNum,rightNum,opera);} else { // 终结表达式return new TerminalExpression().interpreter(text);}}private int findEndBracketPos(String text) {int startPos = 0,endPos = 0;do {endPos = text.indexOf(")",endPos+1);startPos = text.indexOf("(",startPos+1);} while (startPos < endPos && startPos > 0);return endPos;}}/*** 是一个数值 或者 是 (数值) 形式,要把text 转换为数值*/private static class TerminalExpression extends Expression {@Overrideint interpreter(String text) {
// System.out.println("TerminalExpression:" + text);if (text.indexOf("(") == 0) {text = text.substring(1,text.length() - 1);}return Integer.parseInt(text);}}}
2.2 优缺点
优点:
- 实现文法较为容易。易于改变和扩展文法。增加新的解释表达式较为方便,只需增加相关表达式类即可,符合开闭原则。
缺点:
- 执行效率较低,使用了大量的循环和递归调用,调试过程比较麻烦。
- 复杂文法难以维护。如果一种语言包含太多文法规则,类的数量将会急剧增加,导致系统难以管理和维护。
相关文章:

【再探】设计模式—备忘录模式与解释器模式
备忘录模式是用于保存对象在某个时刻的状态,来实现撤销操作。而解释器模式则是将文本按照定义的文法规则解析成对应的命令。 1 备忘录模式 需求:保存对象在某个时刻的状态,后面可以对该对象实行撤销操作。 1.1 备忘录模式介绍 提供一种状…...

SpringCloud网关-gateway
一 什么是网关?为什么选择 Gateway? 网关功能如下: 身份认证和权限校验服务路由、负载均衡请求限流 在 Spring Cloud 中网关的实现包含两种: Gateway(推荐):是基于 Spring5 中提供的 WebFlux ÿ…...

LiveData是如何感知Room数据变化的
一 Room数据变化LiveData如何收到onChanged回调的? 1.1 LiveData是如何创建的 这里讨论的LiveData的创建是特指Dao定义的方法的返回类型,而不是所有的LiveData。 以NoteDao 举例: Dao public interface NoteDao {Query("select * fr…...

【自动化】WebUI自动化通过读取用户数据的方式启动浏览器实现绕过相关登录验证的方法。
背景说明 我相信做自动化测试或者实现UI自动化相关功能的同学肯定碰到过,每次写好脚本执行时都是默认打开一个 “新”的浏览器,我的意思是就跟刚下载的浏览器一样。而不是平时日常使用着的浏览器的状态,日常使用浏览器时只要近期登录过&…...

信号:干扰类别及特征提取
目录 第一部分:干扰类别 1.压制干扰 1.1噪声调幅瞄准式干扰(单音干扰) 1.2噪声调频阻塞式干扰(宽带噪声干扰) 1.3噪声调频扫频式干扰(线性调频) 2.欺骗干扰 2.1距离欺骗干扰(幅度调制干扰࿰…...

【推荐】用scss循环zoom缩放比例,解决可视化大屏在不同分辨率屏幕下的适配问题
方法1: 指定几种常规屏幕宽度(用这种方式就必须要强制用户全屏查看页面,在固定的宽度下才能达到比较不错的显示效果) // 适配不同分辨率的页面---------------------------------------- html {overflow: hidden;width: 1920px;…...

23中设计模式之一— — — —命令模式的详细介绍
命令模式 Command Pattern讲解 概念描述模式结构主要角色模式的UIM类图模式优点模式缺点应用场景实例演示类图代码演示运行结果 概念 命令模式(别名:动作,事务) 命令模式是一种行为设计模式,将一个请求封装为一个对象…...

解决 Mac Django 连接Mysql 出现 image not found 问题
最近在使用 Django 框架,因为升级到4.2版本了,对应的本机 Mysql 5.7 就不适用了,于是升级到了 Mysql 8.0,写好代码之后出现如下错误: 仔细分析一下错误的描述: ImportError: dlopen(/Library/Frameworks/P…...

EitbaseEX香港业务开展,提升用户友好交易体验
在全球范围内备受瞩目的加密货币交易平台Coinbase,宣布正式入驻香港市场,并命名为EitbaseEX。这一战略性扩展举措,旨在为香港提供先进的加密货币交易技术和服务,同时将香港打造为其在亚太地区的重要枢纽。 作为国际金融中心&#…...

ROS学习记录:自定义消息类型
前言 当我们需要传输一些特殊的数据时,且官方的消息包无法满足需求,我们便可以自己定义一个消息类型。 实验步骤 一、在终端输入cd ~/catkin_ws1/src进入工作空间中src目录 二、输入catkin_create_pkg qq_msgs roscpp rospy std_msgs message_generati…...

创新实训2024.06.06日志:部署web服务
1. 运行web项目前后端服务 首先我们要先在服务器上运行客户端以及服务端的应用程序。随后再考虑如何通过公网/局域网访问的问题。 如何启动服务在仓库对应分支下的Readme文件中已经有详细描述了。 1.1. 启动服务端 对于服务端,即(要求你在服务端子项…...

使用C++实现YOLO图像分类:从环境搭建到性能评估的完整指南
⭐️我叫忆_恒心,一名喜欢书写博客的研究生👨🎓。 如果觉得本文能帮到您,麻烦点个赞👍呗! 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三连支…...

Linux中安装Docker,并使用Docker安装MySQL和Redis
1、安装docker 1卸载系统之前的docker yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine2、安装Docker-CE #安装必须的依赖 sudo yum install -y yum-utils \device-map…...

期货短线交易的核心技术是什么
一、市场分析是短线交易的基础: 技术分析在短线交易中尤为重要,包括K线图、均线系统、成交量与持仓量等指标。K线图可以帮助交易者识别关键价格形态和趋势线,从而判断市场走势。均线系统则可以利用短期均线交叉作为买卖信号,如金…...

VSCode+Vite+Vue3断点调试
目录 lunch.json创建 vite.config.ts 打断点运行 lunch.json创建 首先,点击VSCode左上角,甲壳虫运行的按钮,然后点击运行与调试,选择chrome浏览器,修改成一下配置。 { // 使用 IntelliSense 了解相关属性。 // 悬停…...

RPC框架原理(一)
RPC框架原理 网络和IO的关系,IO(input和output)面向的是谁?OSI 7层参考模型,TCP/IP协议为什么会出现一个会话层三次握手socket心跳keep alive四次挥手 网络IO(IO模型) IO框架底层 学习顺序&…...

LCTF 2018 bestphp‘s revenge
考点:Soap原生类Session反序列化CRLF注入 <?php highlight_file(__FILE__); $b implode; call_user_func($_GET[f], $_POST); session_start(); if (isset($_GET[name])) { $_SESSION[name] $_GET[name]; } var_dump($_SESSION); $a array(reset($_…...

MySQL主从搭建--保姆级教学
MYSQL主从搭建步骤 主节点 # 进入目录 cd /opt# 下载安装包 wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz# 解压 tar -xvf mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz# 拷贝到/usr/local mv /opt/mysql-8.0.20-linux-g…...

Modbus通信协议--RTU
一、RTU介绍 MODBUS协议支持多种功能码,不同的功能码对应不同的操作: 0x01读线圈状态0x02读离散输入状态0x03读保持寄存器0x04读输入寄存器0x05写单个线圈0x06写单个保持寄存器0x0F写多个线圈0x10写多个保持寄存器 二、实验 1.0x03功能码读单个保持寄…...

我是大学生,应该选系统运维方向,还是web开发方向?
选择系统运维方向还是Web开发方向取决于你的兴趣、职业目标和个人技能。以下是对这两个方向的详细对比和建议,帮助你做出更明智的选择 双方比较 🤦♀️系统运维方向 优点: 稳定性:系统运维工作通常比较稳定,许多…...

Qt窗口与对话框
目录 Qt窗口 1.菜单栏 2.工具栏 3.状态栏 4.滑动窗口 QT对话框 1.基础对话框QDiaog 创建新的ui文件 模态对话框与非模态对话框 2.消息对话框 QMessageBox 3.QColorDialog 4.QFileDialog文件对话框 5.QFontDialog 6.QInputDialog Qt窗口 前言:之前以上…...

【笔记】Windows 中 一键部署本地私人专属知识库:MaxKB + Docker + MaxKB docker + Ollama
Docker的部署: Docker下载直接进入链接: https://www.docker.com/ Docker使用需要启动Docker,启动Docker以后,会在桌面右下角看到Docker的一个图标: 只有启动了Docker以后,Docker的各种命令才可以使用。 好像还需要…...

【Vue】scoped解决样式冲突
默认情况下写在组件中的样式会 全局生效 → 因此很容易造成多个组件之间的样式冲突问题。 全局样式: 默认组件中的样式会作用到全局,任何一个组件中都会受到此样式的影响 局部样式: 可以给组件加上scoped 属性,可以让样式只作用于当前组件 一、代码示例 BaseOne…...

word模板内容替换
1.pom引入依赖: <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.5</version> </dependency> <dependency><groupId>com.deepoove</groupId><a…...

docker安装和使用
1. docker-ce Docker Community Edition (CE): 功能: 这是 Docker 的主要组件,用于创建、管理和运行容器。它包括 Docker 守护进程 (dockerd),该守护进程负责处理容器的生命周期,包括创建、启动、停止和删除容器。用途: 允许用户在其系统上…...

【AIGC X UML 落地】通过多智能体实现自然语言绘制UML图
前天写了篇博文讲到用PlantUML来绘制C类图和流程图。后台有读者留言,问这步能否自动化生成,不想学习 PlantUML 语法。 我想了下,发现这事可行,确实可以做到通过自然语言的描述就能实现 UML图的绘制,昨天晚上加了个班到…...

C++访问越界
常见场景 访问数组元素越界vector容器访问等 vector<int>;vec<2>;字符串访问越界string str;str[2];array数组访问越界字符串处理,没有添加’\0’字符,导致访问字符串的时候越界了;使用类型强转,让一个大…...

MATLAB format
在MATLAB中,format 是一个函数,用于控制命令窗口中数值的显示格式。这个函数可以设置数值的精度、显示的位数等。以下是一些常用的 format 命令: format long:以默认的长格式显示数值,通常显示15位有效数字。format s…...

Face Forgery Detection by 3D Decomposition
文章目录 Face Forgery Detection by 3D Decomposition研究背景研究目标创新点方法提出问题研究过程技术贡献实验结果未来工作Face Forgery Detection by 3D Decomposition 会议:CVPR2021 作者: 研究背景 面部伪造引发关注传统面部伪造检测主要关注原始RGB图像研究目标 将…...

socket网络编程——多进程、多线程处理并发
如下图所示, 当一个客户端与服务器建立连接以后,服务器端 accept()返回,进而准备循环接收客户端发过来的数据。 如果客户端暂时没发数据,服务端会在 recv()阻塞。此时,其他客户端向服务器发起连接后,由于服务器阻塞了,无法执行 accept()接受连接,也就是其他客户端发送…...