前言
目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~
本节给大家讲一下设计模式中的解释器模式,并结合实际业务场景给大家讲解如何使用~
本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~
解释器模式
解释器模式(Interpreter Pattern)是一种行为型设计模式,它定义了一种语言的语法表示,并定义了一个解释器来解释这种语言中的表达式。通过使用解释器模式,可以轻松地扩展和修改语言的语法,从而使其更加灵活。
该模式的结构包含以下组件:
抽象表达式(AbstractExpression):定义了一个解释器中的抽象操作,每个具体的解释器都实现了该抽象操作。终结符表达式(TerminalExpression):定义了一个解释器中的终止操作,它不能再进行解释。非终结符表达式(NonterminalExpression):定义了一个解释器中的非终止操作,它可以递归调用其他解释器进行解释。环境(Context):保存了解释器需要的一些全局信息。
下面我们举一个大家日常开发中最常用的定时任务的例子:
// 抽象表达式
// 抽象表达式接口
public interface Expression {
boolean interpret(String expression);
}
// 秒表达式
public class SecondExpression implements Expression {
@Override
public boolean interpret(String expression) {
// 解析表达式,判断秒数是否匹配
return true; // 返回是否匹配
}
}
// 分钟表达式
public class MinuteExpression implements Expression {
@Override
public boolean interpret(String expression) {
// 解析表达式,判断分钟数是否匹配
return true; // 返回是否匹配
}
}
// 小时表达式
public class HourExpression implements Expression {
@Override
public boolean interpret(String expression) {
// 解析表达式,判断小时数是否匹配
return true; // 返回是否匹配
}
}
// 日表达式
public class DayOfMonthExpression implements Expression {
@Override
public 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;
}
@Override
public 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;
}
@Override
public 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
}
}
上述仅仅是一个简单的示例,实际应用中可能会更加复杂。例如,可能需要实现更多的折扣规则类型,或者添加更多的操作和函数。但是,无论怎样扩展和修改折扣系统的规则,解释器模式都可以帮助我们轻松地完成这些任务。
结束语
设计模式其实并不难,大家在学习的时候一定要在理解的基础上去写代码,不要去背代码。下节给大家讲迭代器模式~
本着把自己知道的都告诉大家,如果本文对您有所帮助,点赞+关注鼓励一下呗~
相关文章
- 一起来学设计模式之认识设计模式
- 一起来学设计模式之单例模式
- 一起来学设计模式之工厂模式
- 一起来学设计模式之建造者模式
- 一起来学设计模式之原型模式
- 一起来学设计模式之适配器模式
- 一起来学设计模式之桥接模式
- 一起来学设计模式之组合模式
- 一起来学设计模式之装饰器模式
- 一起来学设计模式之外观模式
- 一起来学设计模式之享元模式
- 一起来学设计模式之代理模式
- 一起来学设计模式之责任链模式
- 一起来学设计模式之命令模式
项目源码(源码已更新 欢迎star⭐️)
Kafka 专题学习
- 一起来学kafka之Kafka集群搭建
- 一起来学kafka之整合SpringBoot基本使用
- 一起来学kafka之整合SpringBoot深入使用(一)
- 一起来学kafka之整合SpringBoot深入使用(二)
- 一起来学kafka之整合SpringBoot深入使用(三)
项目源码(源码已更新 欢迎star⭐️)
ElasticSearch 专题学习
项目源码(源码已更新 欢迎star⭐️)
往期并发编程内容推荐
- Java多线程专题之线程与进程概述
- Java多线程专题之线程类和接口入门
- Java多线程专题之进阶学习Thread(含源码分析)
- Java多线程专题之Callable、Future与FutureTask(含源码分析)
- 面试官: 有了解过线程组和线程优先级吗
- 面试官: 说一下线程的生命周期过程
- 面试官: 说一下线程间的通信
- 面试官: 说一下Java的共享内存模型
- 面试官: 有了解过指令重排吗,什么是happens-before
- 面试官: 有了解过volatile关键字吗 说说看
- 面试官: 有了解过Synchronized吗 说说看
- Java多线程专题之Lock锁的使用
- 面试官: 有了解过ReentrantLock的底层实现吗?说说看
- 面试官: 有了解过CAS和原子操作吗?说说看
- Java多线程专题之线程池的基本使用
- 面试官: 有了解过线程池的工作原理吗?说说看
- 面试官: 线程池是如何做到线程复用的?有了解过吗,说说看
- 面试官: 阻塞队列有了解过吗?说说看
- 面试官: 阻塞队列的底层实现有了解过吗? 说说看
- 面试官: 同步容器和并发容器有用过吗? 说说看
- 面试官: CopyOnWrite容器有了解过吗? 说说看
- 面试官: Semaphore在项目中有使用过吗?说说看(源码剖析)
- 面试官: Exchanger在项目中有使用过吗?说说看(源码剖析)
- 面试官: CountDownLatch有了解过吗?说说看(源码剖析)
- 面试官: CyclicBarrier有了解过吗?说说看(源码剖析)
- 面试官: Phaser有了解过吗?说说看
- 面试官: Fork/Join 有了解过吗?说说看(含源码分析)
- 面试官: Stream并行流有了解过吗?说说看