【设计模式】设计模式之解释器模式
文章目录
- 前言
- 一、解释器模式
- 二、最佳实践
- 总结
前言
本节给大家讲一下设计模式中的解释器模式,并结合实际业务场景给大家讲解如何使用~
所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整~
一、解释器模式
解释器模式(Interpreter Pattern)是一种行为型设计模式,它定义了一种语言的语法表示,并定义了一个解释器来解释这种语言中的表达式。
通过使用解释器模式,可以轻松地扩展和修改语言的语法,从而使其更加灵活。
该模式的结构包含以下组件:
- 抽象表达式(AbstractExpression):定义了一个解释器中的抽象操作,每个具体的解释器都实现了该抽象操作。
- 终结符表达式(TerminalExpression):定义了一个解释器中的终止操作,它不能再进行解释。
- 非终结符表达式(NonterminalExpression):定义了一个解释器中的非终止操作,它可以递归调用其他解释器进行解释。
- 环境(Context):保存了解释器需要的一些全局信息。
下面我们举一个大家日常开发中最常用的定时任务的例子:
// 抽象表达式
// 抽象表达式接口
public interface Expression {boolean interpret(String expression);
}// 秒表达式
public class SecondExpression implements Expression {@Overridepublic boolean interpret(String expression) {// 解析表达式,判断秒数是否匹配return true; // 返回是否匹配}
}// 分钟表达式
public class MinuteExpression implements Expression {@Overridepublic boolean interpret(String expression) {// 解析表达式,判断分钟数是否匹配return true; // 返回是否匹配}
}// 小时表达式
public class HourExpression implements Expression {@Overridepublic boolean interpret(String expression) {// 解析表达式,判断小时数是否匹配return true; // 返回是否匹配}
}// 日表达式
public class DayOfMonthExpression implements Expression {@Overridepublic boolean interpret(String expression) {// 解析表达式,判断日期是否匹配return true; // 返回是否匹配}
}// 定时任务表达式
public class CronExpression implements Expression {private Expression secondExpression;private Expression minuteExpression;private Expression hourExpression;private Expression dayOfMonthExpression;public CronExpression(Expression secondExpression, Expression minuteExpression,Expression hourExpression, Expression dayOfMonthExpression) {this.secondExpression = secondExpression;this.minuteExpression = minuteExpression;this.hourExpression = hourExpression;this.dayOfMonthExpression = dayOfMonthExpression;}@Overridepublic boolean interpret(String expression) {String[] fields = expression.split(" ");// 解析定时任务表达式,判断各个字段是否匹配boolean matchSecond = secondExpression.interpret(fields[0]);boolean matchMinute = minuteExpression.interpret(fields[1]);boolean matchHour = hourExpression.interpret(fields[2]);boolean matchDayOfMonth = dayOfMonthExpression.interpret(fields[3]);return matchSecond && matchMinute && matchHour && matchDayOfMonth;}
}public class Client {public static void main(String[] args) {// 创建表达式对象Expression second = new SecondExpression();Expression minute = new MinuteExpression();Expression hour = new HourExpression();Expression dayOfMonth = new DayOfMonthExpression();Expression cron = new CronExpression(second, minute, hour, dayOfMonth);// 判断定时任务是否应该被执行String expression = "0 0 1 * *"; // 每月1日执行任务boolean match = cron.interpret(expression);if (match) {System.out.println("定时任务执行中...");} else {System.out.println("定时任务未开始...");}}
}
当定时任务表达式为0 0 1 * *时,表示该定时任务在每个月的1日执行。如果当前日期是1日,那么match变量的值将为true,表示该定时任务应该被执行。否则,match变量的值将为false,表示该定时任务还未开始执行。表达式内部具体规则逻辑可以自行实现,这里只是为了方便演示~
二、最佳实践
在电商平台中,可以使用解释器模式来实现一个基于规则的折扣系统。该系统可以根据用户的购物车内容和优惠规则来计算出最终的折扣金额。
下面是一个示例,展示了如何使用解释器模式来实现一个基于规则的折扣系统:
// 抽象表达式
interface DiscountExpression {double interpret(ShoppingCart cart);
}// 终结符表达式:商品价格
class ItemPrice implements DiscountExpression {private String itemId;public ItemPrice(String itemId) {this.itemId = itemId;}public double interpret(ShoppingCart cart) {double price = 0;for (CartItem item : cart.getItems()) {if (item.getItemId().equals(itemId)) {price += item.getPrice() * item.getQuantity();}}return price;}
}// 终结符表达式:折扣价格
public class DiscountPrice implements DiscountExpression {private double discount;public DiscountPrice(double discount) {this.discount = discount;}@Overridepublic double interpret(ShoppingCart cart) {double price = 0;for (CartItem item : cart.getItems()) {price += item.getPrice() * item.getQuantity() * discount;}return price;}
}// 终结符表达式:购物车总价
class CartTotal implements DiscountExpression {public double interpret(ShoppingCart cart) {double total = 0;for (CartItem item : cart.getItems()) {total += item.getPrice() * item.getQuantity();}return total;}
}// 非终结符表达式:满减
class Discount implements DiscountExpression {private DiscountExpression condition;private DiscountExpression action;public Discount(DiscountExpression condition, DiscountExpression action) {this.condition = condition;this.action = action;}public double interpret(ShoppingCart cart) {if (condition.interpret(cart) > 0) {return action.interpret(cart);}return 0;}
}// 环境:购物车
class ShoppingCart {private List<CartItem> items;public ShoppingCart() {items = new ArrayList<>();}public void addItem(CartItem item) {items.add(item);}public List<CartItem> getItems() {return items;}
}// 环境:购物车商品项
class CartItem {private String itemId;private String itemName;private double price;private int quantity;public CartItem(String itemId, String itemName, double price, int quantity) {this.itemId = itemId;this.itemName = itemName;this.price = price;this.quantity = quantity;}public String getItemId() {return itemId;}public String getItemName() {return itemName;}public double getPrice() {return price;}public int getQuantity() {return quantity;}
}// 客户端
public class DiscountSystemDemo {public static void main(String[] args) {// 初始化购物车ShoppingCart cart = new ShoppingCart();cart.addItem(new CartItem("001", "商品1", 100, 2));cart.addItem(new CartItem("002", "商品2", 200, 1));// 定义折扣规则DiscountExpression rule1 = new Discount(new ItemPrice("001"), new DiscountPrice(0.1));DiscountExpression rule2 = new Discount(new ItemPrice("002"), new DiscountPrice(0.2));// 计算折扣double discount1 = rule1.interpret(cart);double discount2 = rule2.interpret(cart);double totalDiscount = discount1 + discount2;// 输出结果System.out.println("折扣总额:" + totalDiscount);System.out.println("应付金额:" + (new CartTotal().interpret(cart) - totalDiscount));// 折扣总额:120.0
// 应付金额:280.0}
}
上述仅仅是一个简单的示例,实际应用中可能会更加复杂。例如,可能需要实现更多的折扣规则类型,或者添加更多的操作和函数。但是,无论怎样扩展和修改折扣系统的规则,解释器模式都可以帮助我们轻松地完成这些任务。
总结
解释器模式其实并不难,大家在学习的时候一定要在理解的基础上去写代码,不要去背代码。
相关文章:
【设计模式】设计模式之解释器模式
文章目录 前言一、解释器模式二、最佳实践总结 前言 本节给大家讲一下设计模式中的解释器模式,并结合实际业务场景给大家讲解如何使用~ 所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整~ 一、解释器模式 解释器模式(Interpreter Pattern)…...
leetcode551. 学生出勤记录 I
题目描述解题思路执行结果 leetcode551. 学生出勤记录 I . 题目描述 给你一个字符串 s 表示一个学生的出勤记录,其中的每个字符用来标记当天的出勤情况(缺勤、迟到、到场)。记录中只含下面三种字符: A:Absentÿ…...
flume拦截器介绍
Flume是一个开源的、分布式的、可靠的、高效的海量数据采集、聚合和传输系统。其中,拦截器(Interceptor)是Flume中的一种组件,可以在数据(Event)流动的各个阶段对数据进行处理、过滤或转换,从而实现更为灵活、高效的数据采集和传输。 1、拦截…...
5.4、服务器编程基本框架和两种高效的事件处理模式
5.4、服务器编程基本框架和两种高效的事件处理模式 1.服务器编程基本框架2.两种高效的事件处理模式①Reactor模式②Proactor模式③模拟Proactor模式 1.服务器编程基本框架 模块功能I/O 处理单元处理客户连接,读写网络数据逻辑单元业务进程或线程网络存储单元数据库、…...
Flink主要有两种基础类型的状态:operator state。
Flink主要有两种基础类型的状态:keyed state 和operator state。 Operator State 对于Operator State(或者non-keyed state),每个operator state绑定到一个并行operator实例上。在Flink中,Kafka Connector是一个使用Operator State的很好的例…...
【vue2】使用vue-admin-template动态添加路由的思路/addRoutes的使用
😉博主:初映CY的前说(前端领域) ,📒本文核心:用原生js实现省市区联动 【前言】在通用的后台管理项目的开发中,不仅仅是会涉及到对表单数据等的增删改查操作还会涉及到一些关于权限管理的问题。我们将基于一个RBAC的思维…...
Python语言中的注释方法应用
Python语言中的注释方法 在Python编程中,与其他编程语言一样,有良好的注释部分,会让你的程序在后续的改进或优化中,变得便利。同时,给自己培养了良好的编程习惯。 在Python语言中,有两种注释方法。 1.单行…...
Google浏览器翻译无法正常使用解决
1.查找可用服务器地址 按WinR键打开运行→输入cmd回车,打开命令提示符→输入ping google.cn 回车。记录一下下图红框里的ip地址,一会要用到 最近自己ping出来的ip可能不能用了,可以尝试用下面的ip 142.251.163.90 142.250.113.90 142.251.…...
ETCD(三)操作指令
1. put put #将给定的key写入到存储 --ignore-lease[false] #使用当前租约更新key --ignore-value[false] #使用当前值更新key --lease"0" # 要附加到key的租约ID(十六进制) --prev-kv[false] # 返回修改前的上一个键值对2. get get #获取给…...
小白学Pytorch系列--Torch.optim API Base class(1)
小白学Pytorch系列–Torch.optim API Base class(1) torch.optim是一个实现各种优化算法的包。大多数常用的方法都已得到支持,而且接口足够通用,因此将来还可以轻松集成更复杂的方法。 如何使用优化器 使用手torch.optim您必须构造一个优化器对象&…...
flac格式如何转mp3,3招帮你搞定
flac格式如何转mp3,3招帮你搞定的方法来啦。当你的音频是flac格式是不是很头疼,又不知道怎么转mp3 。然后网上搜索出很多方法又不知道从哪个下手,是不是很疑惑?那今天就来看看小编推荐的方法吧,一定让你眼前一亮&#…...
Redis入门到入土(day01)
NoSQL概述 为什么用NoSQL 1、单机MySQL的美好年代 在90年代,一个网站的访问量一般不大,用单个数据库完全可以轻松应付! 在那个时候,更多的都是静态网页,动态交互类型的网站不多。 上述架构下,我们来看看…...
JVM垃圾回收GC 详解(java1.8)
目录 垃圾判断算法(你是不是垃圾?) 引用计数法 可达性算法 对象的引用 强引用 软引用 弱引用 虚引用 对象的自我救赎 垃圾回收算法--分代 标记清除算法 复制算法 标记整理法 垃圾处理器 垃圾判断算法(你是不是垃圾&…...
Mybatis-Plus -03 Mybatis-Plus实现CRUD
Mybatis-Plus实现CRUD 1 Insert增加2 ID生成策略3 Delete删除4 逻辑删除5 Update修改6 Select查询 Mybatis-Plus实现CRUD 通用 CRUD 封装**BaseMapper (opens new window)**接口,为 Mybatis-Plus 启动时自动解析实体表关系映射转换为 Mybatis 内部对象注入容器参数 …...
综合能源系统中基于电转气和碳捕集系统的热电联产建模与优化研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
“智慧赋能 强链塑链”|工程物资供应链管理中的数字化应用
工程项目中的供应链管理至关重要 工程建设行业是国民经济的重要支柱之一,虽然在总产值上持续保持增长态势,但近年来行业的利润总额增速已连续多年呈现下降趋势。究其原因,可以大体从两个方面来看:一是行业盈利能力出现下降&#x…...
通过docker发布项目
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言例如:docker项目的发布方式 [docker发布的参考链接](https://www.cnblogs.com/emperorking/articles/11244253.html) 一、docker是什么?…...
为什么Spring和IDEA不推荐使用@Autowired注解?
在Spring开发中,Autowired注解是一个常用的依赖注入方式。但是,你可能会惊奇地发现,Spring和IDEA都不推荐使用Autowired注解。关于这个问题,其实答案相对统一,实际上用大白话说起来也容易理解。 官方答案 首先&#…...
windows下运行dpdk下的helloworld
打开“本地安全策略”管理单元,在搜索框输入secpol。 打开本地策略->用户权限分配->锁定内存页->添加用户或组->高级->立即查找 输入电脑用户名,选择并添加。点击确定后,重启电脑。 安装内核驱动,下载地址https://download.csdn.net/download/qq_36314864…...
【AI理论学习】深入理解Prompt Learning和Prompt Tuning
深入理解Prompt Learning和Prompt Tuning 背景Prompt Learning简介1. Prompt是什么?2. 为什么要使用Prompt?3. Prompt Learning的形式(举例)4. 有哪些Pre-training language model?5. 常见的Prompt Learning的方法 Pro…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!
目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...
五子棋测试用例
一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏,有着深厚的文化底蕴。通过将五子棋制作成网页游戏,可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家,都可以通过网页五子棋感受到东方棋类…...
