设计模式(22):解释器模式

解释器

  • 是一种不常用的设计模式
  • 用于描述如何构成一个简单的语言解释器,主要用于使用面向对象语言开发的解释器和解释器设计
  • 当我们需要开发一种新的语言时,可以考虑使用解释器模式
  • 尽量不要使用解释器模式,后期维护会有很大麻烦。在项目中,可以使用jruby、groovy、java的js引擎来替代解释器的作用,弥补java语言的不足。

开发中常见的场景

  • EL表达式的处理
  • 正则表达式解释器
  • SQL语法的解释器
  • 数学表达式解释器

举例代码实现

  • 解析和执行数学表达式
    输入"5+4*5-8/4",输出“23”
  • 抽象解释器接口
/*** 抽象解释器接口*/
public interface Expression {int interpret(Context context);
}
  • 终结符表达式
/*** 数值表达式---终结符表达式*/
public class NumberExpression implements Expression{private Integer number;public NumberExpression(Integer number) {super();this.number = number;}@Overridepublic int interpret(Context context) {return number;}
}
/*** 运算符号表达式---终结符表达式* 	symbol:* 		1:加 * 		2:减 * 		3:乘 * 		4:除 */
public class SymbolExpression implements Expression {private int symbol;	public SymbolExpression(int symbol) {super();this.symbol = symbol;}@Overridepublic int interpret(Context context) {return symbol;}
}
  • 非终结符表达式
/*** 加法表达式——加法表达式也是数值表达式的一种*/
public class AdditionExpression extends NumberExpression{private NumberExpression left;private NumberExpression right;public AdditionExpression(NumberExpression left, NumberExpression right) {super(1);this.left = left;this.right = right;}@Overridepublic int interpret(Context context) {return left.interpret(context) + right.interpret(context);}
}
/*** 减法表达式---减法表达式也是数值表达式的一种*/
public class SubtractExpression extends NumberExpression{private NumberExpression left;private NumberExpression right;public SubtractExpression(NumberExpression left, NumberExpression right) {super(2);this.left = left;this.right = right;}@Overridepublic int interpret(Context context) {return left.interpret(context) - right.interpret(context);}
}
/*** 乘法表达式——乘法表达式也是数值表达式的一种*/
public class MultiplicationExpression extends NumberExpression{private NumberExpression left;private NumberExpression right;public MultiplicationExpression(NumberExpression left, NumberExpression right) {super(3);this.left = left;this.right = right;}@Overridepublic int interpret(Context context) {return left.interpret(context) * right.interpret(context);}
}
/*** 除法表达式——除法表达式也是数值表达式的一种*/
public class DivisionExpression extends NumberExpression{private NumberExpression left;private NumberExpression right;public DivisionExpression(NumberExpression left, NumberExpression right) {super(4);this.left = left;this.right = right;}@Overridepublic int interpret(Context context) {return left.interpret(context) / right.interpret(context);}
}
  • 上下文类(context)
public class Context {private Expression expression;public Context(String expression) {LinkedList<Expression> linkedList = new LinkedList<Expression>();int num = 0;for(int i=0;i<expression.length();i++) {char ati;if((ati=expression.charAt(i))>='0' && ati<='9') {num = num*10 + (ati-'0');}else {Expression peek;SymbolExpression symbol;NumberExpression left,right;if(!linkedList.isEmpty() && ((peek=linkedList.peekLast()) instanceof SymbolExpression) && (peek.interpret(this)==3 || peek.interpret(this)==4)){symbol = (SymbolExpression)linkedList.pollLast();left = (NumberExpression)linkedList.pollLast();right = new NumberExpression(num);if(symbol.interpret(this)==3){linkedList.addLast(new MultiplicationExpression(left, right));}else{linkedList.addLast(new DivisionExpression(left, right));}}else{linkedList.addLast(new NumberExpression(num));}SymbolExpression symbolExpression = null;switch (ati) {case '+':symbolExpression = new SymbolExpression(1);break;case '-':symbolExpression = new SymbolExpression(2);break;case '*':symbolExpression = new SymbolExpression(3);break;case '/':symbolExpression = new SymbolExpression(4);break;default:break;}num = 0;linkedList.addLast(symbolExpression);}}Expression peek;if(!linkedList.isEmpty() &&(	(peek=linkedList.peekLast()) instanceof SymbolExpression) && (peek.interpret(this)==3 || peek.interpret(this)==4)){Expression symbol = linkedList.pollLast();NumberExpression left = (NumberExpression)linkedList.pollLast();NumberExpression right = new NumberExpression(num);if(symbol.interpret(this)==3){linkedList.addLast(new MultiplicationExpression(left, right));}else{linkedList.addLast(new DivisionExpression(left, right));}}else{linkedList.add(new NumberExpression(num));}init(linkedList);}private void init(LinkedList<Expression> linkedList){SymbolExpression symbolExpression = null;NumberExpression left = null;while(!linkedList.isEmpty()){Expression tempExpression = linkedList.pollFirst();if(tempExpression instanceof SymbolExpression){symbolExpression = (SymbolExpression)tempExpression;}else{if(left==null){left = (NumberExpression)tempExpression;}else{NumberExpression right = (NumberExpression)tempExpression;switch (symbolExpression.interpret(this)) {case 1:left = new AdditionExpression(left, right);break;case 2:left = new SubtractExpression(left, right);break;case 3:left = new MultiplicationExpression(left, right);break;case 4:left = new DivisionExpression(left, right);break;default:break;}}}}this.expression = left;}public int calculate(){return this.expression.interpret(this);}
}
  • 客户端调用
public static void main(String[] args) {Context context = new Context("33+12*9+42/2+6/3");int calculate = context.calculate();System.out.println(calculate);
}
  • 结果
    在这里插入图片描述





更多设计模式学习:

          设计模式(1):介绍
          设计模式(2):单例模式
          设计模式(3):工厂模式
          设计模式(4):建造者模式
          设计模式(5):原型模式
          设计模式(6):桥接模式
          设计模式(7):装饰器模式
          设计模式(8):组合模式
          设计模式(9):外观模式
          设计模式(10):享元模式
          设计模式(11):适配器模式
          设计模式(12):代理模式
          设计模式(13):模板方法模式
          设计模式(14):命令模式
          设计模式(15):迭代器模式
          设计模式(16):观察者模式
          设计模式(17):中介者模式
          设计模式(18):状态模式
          设计模式(19):策略模式
          设计模式(20):责任链模式
          设计模式(21):备忘录模式
          设计模式持续更新中…

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

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

相关文章

vue+springboot实现JWT登录验证

目录 前言概念实际演示路由信息初始访问登录界面登录验证验证过期 vue实现依赖引入main.js获取和设置token工具类登录方法实体登录方法axios请求 router配置 springboot实现依赖引入JWT工具类忽视jwt验证注解拦截器逻辑跨域&调用拦截器配置登录接口&验证token接口 结语…

【软考】下午题:面向对象与程序设计【接口、抽象类、this、super使用】

文章目录 1、位运算符2、特殊关键字的使用&#xff1a;break、continue3、成员变量&#xff08;类的属性&#xff09;和局部变量的区别4、this关键字5、super关键字6、抽象类与abstract关键字7、接口8、Java权限修饰符 1、位运算符 注意&#xff1a; ①右移根据最高位是0&#…

SOLIDWORKS如何新建定义材质库

SolidWorks材质库中包含了大量的材料选项&#xff0c;涵盖了金属、塑料、橡胶、复合材料等各种类型&#xff0c;每种材料都有详细的特性参数。用户可以根据设计需求&#xff0c;在材质库中选择合适的材料&#xff0c;从而更好地满足设计要求。在有限元分析中&#xff0c;需要附…

统一用安卓Studio修改项目包名

可以逃跑&#xff0c;可以哭泣&#xff0c;但不可以放弃 --《鬼灭之刃》 修改项目包名 1&#xff09;选中项目中药修改的包名&#xff1a; 2)目结构显示方式&#xff0c;取消 Compact Middle Packages 选项&#xff1b; 3)右键要修改的包名&#xff0c;选择 Refactor —— Re…

结构体及联合体大小计算

结构体大小计算 结构体大小的计算的依据是结构体内存对齐 对齐规则&#xff1a; 1.结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处 2.其他成员变量要对齐到某个数字&#xff08;对齐数&#xff09;的整数倍的地址处。 &#xff08;对齐数编译器默认的一个对齐…

超越常规:用PHP抓取招聘信息

在人力资源管理方面&#xff0c;有效的数据采集可以为公司提供宝贵的人才洞察。通过分析招聘网站上的职位信息&#xff0c;人力资源专员可以了解市场上的人才供给情况&#xff0c;以及不同行业和职位的竞争状况。这样的数据分析有助于企业制定更加精准的招聘策略&#xff0c;从…

redis的三大模式的演化及集群模式思考和总结

redis的三大模式&#xff0c;也是循序渐进。 1、主从复制 比如一开始的读写分离的&#xff0c;主从复制。 一个master&#xff0c;多个slave。 master进行写和 增量同步&#xff0c;slave负责读&#xff0c;和接收增量同步的信息。 这样压力减轻。 2、哨兵模式 这个推出…

打印CSDN博客只需两步

打印博客 关闭浏览器限制 浏览器打开对应博客&#xff0c;F12&#xff0c;在console下粘贴如下代码&#xff0c;回车 (function doPrint(){var head_str "<html><head><title></title></head><body>"; var foot_str "&…

4月9日学习记录

[GXYCTF 2019]禁止套娃 涉及知识点&#xff1a;git泄露&#xff0c;无参数RCE 打开环境&#xff0c;源码什么的都没有&#xff0c;扫描后台看看 扫描发现存在git泄露 用githack下载查看得到一串源码 <?php include "flag.php"; echo "flag在哪里呢&#…

go websocket

WebSocket 是一种网络协议&#xff0c;建立在 HTTP 协议之上&#xff0c;允许双向通信。WebSocket 协议允许服务器发送数据到客户端&#xff0c;同时也可以让客户端向服务器发送数据。WebSocket 使用 HTTP 协议的升级请求和响应来建立连接。WebSocket 的主要优点在于它可以通过…

专题十二、字符串

字符串 1. 字符串字面量1.1 字符串字面量中的转义序列1.2 延续字符串字面量1.3 如何存储字符串字面量1.4 字符串字面量的操作1.5 字符串字面量与字符常量 2. 字符串变量2.1 初始化字符串变量2.2 字符数组与字符指针 3. 字符串的读和写3.1 用 printf 函数和 puts 函数写字符串3.…

【Python系列】pydantic版本问题

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

jdk和Eclipse软件安装与配置(保姆级别教程)

目录 1、jdk的下载、安装、配置 1.1 jdk安装包的的下载地址&#xff1a;Java Archive | Oracle &#xff0c;点击进入&#xff0c;然后找到你想要的版本下载&#xff0c;如下图&#xff1a; 2.1 开始下载&#xff0c;如下图&#xff1a; 3.1 登入Oracle账号就可以立即下载了…

Docker 搭建私有镜像仓库

一、镜像仓库简介 Docker的镜像仓库是一个用于存储和管理Docker镜像的中央位置。镜像仓库的主要作用是提供一个集中的地方&#xff0c;让用户可以上传、下载、删除和共享Docker镜像。镜像仓库又可以分为公共镜像仓库和私有仓库镜像仓库&#xff1a; 公共镜像仓库 Docker Hub 是…

java Web在线考试管理系统用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 在线考试管理系统是一套完善的web设计系统&#xff0c;对理解JSP java 编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,eclipse开发&#xff0c;数据库为Mysql5.0&#xff0c;使…

网络网络层之(7)PPPOE协议

网络网络层之(7)PPPOE协议 Author: Once Day Date: 2024年4月7日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文档可参考专栏&#xff1a;通信网络技术_Once-Day…

LeetCode-94(二叉树的中序遍历)

1.递归 时间复杂度O(n) public List<Integer> inorderTraversal(TreeNode root) {List<Integer> res new ArrayList<>();accessTree(root,res);return res;}public void accessTree(TreeNode root,List<Integer>res){if(root null){return;}accessT…

最新剧透前沿信息GPT-5或将今年发布

GPT2 很糟糕 &#xff0c;GPT3 很糟糕 &#xff0c;GPT4 可以 &#xff0c;但 GPT5 会很好。 PS:GPT2 很糟糕,3 很糟糕,4 可以,5 很可以。 如果想升级GPT4玩玩&#xff0c;地址 今年发布的具有推理功能的 GPT5不断发展&#xff0c;就像 iPhone 一样 Sam Altman 于 17 日&am…

OpenAI曾转录100万小时视频数据,训练GPT-4

4月7日&#xff0c;纽约时报在官网发布了一篇名为《科技巨头如何挖空心思&#xff0c;为AI收集数据》的技术文章。 纽约时报表示&#xff0c;OpenAI曾在2021年几乎消耗尽了互联网有用的文本数据源。为了缓解训练数据短缺的难题&#xff0c;便开发了知名开源语音识别模型Whispe…

019——IIC模块驱动开发(基于EEPROM【AT24C02】和I.MX6uLL)

目录 一、 IIC基础知识 二、Linux中的IIC&#xff08;韦东山老师的学习笔记&#xff09; 1. I2C驱动程序的层次 2. I2C总线-设备-驱动模型 2.1 i2c_driver 2.2 i2c_client 三、 AT24C02 介绍 四、 AT24C02驱动开发 实验 驱动程序 应用程序 一、 IIC基础知识 总线类…