一起来学设计模式之解释器模式

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 前言目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~本节给大家讲一下设计模式中的解释器模式,并结合实际业务场景给大家讲解如何使用~本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~解释器模式解释器模式(Interpreter Pattern)是一种行为型设计模式,它定义了一种语言的语法表示,并定义了一个解释器来解释这种语言中的表达式。通过使用解释器模式,可以轻松地扩展和修改语言的语法,从而使其更加灵活。

前言

目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~

本节给大家讲一下设计模式中的解释器模式,并结合实际业务场景给大家讲解如何使用~

本专题的所有案例代码主要以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 专题学习

项目源码(源码已更新 欢迎star⭐️)

ElasticSearch 专题学习

项目源码(源码已更新 欢迎star⭐️)

往期并发编程内容推荐

推荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)

博客(阅读体验较佳)































相关文章
|
设计模式 移动开发 数据库
行为型设计模式10-解释器模式
行为型设计模式10-解释器模式
97 1
|
2月前
|
设计模式 存储 缓存
Java设计模式 - 解释器模式(24)
Java设计模式 - 解释器模式(24)
|
6月前
|
设计模式 SQL Java
【设计模式】抖音一面:你不知道解释器模式?
【设计模式】抖音一面:你不知道解释器模式?
51 1
|
6月前
|
设计模式 Go
[设计模式 Go实现] 行为型~解释器模式
[设计模式 Go实现] 行为型~解释器模式
|
6月前
|
设计模式 存储 Java
小谈设计模式(28)—解释器模式
小谈设计模式(28)—解释器模式
|
6月前
|
设计模式 存储 Java
23种设计模式,解释器模式的概念优缺点以及JAVA代码举例
【4月更文挑战第7天】解释器模式是一种行为设计模式,它用于定义一个语言的语法表示,并提供一个解释器来处理这种语法。主要用于频繁需要解释执行一组固定语法规则的场景,例如编程语言解释器、规则引擎等。
45 3
|
6月前
|
设计模式 存储 SQL
【设计模式系列笔记】解释器模式
解释器模式(Interpreter Pattern)是一种行为型设计模式,它定义了一种语言的文法,并且建立一个解释器来解释该语言中的句子。在Java中,解释器模式通常用于实现编程语言解释器、正则表达式解释器等。
59 0
|
6月前
|
设计模式
【设计模式】解释器模式
【设计模式】解释器模式
|
6月前
|
设计模式 监控 Java
聊聊Java设计模式-解释器模式
解释器模式(Interpreter Design Pattern)指给定一个“语言”,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。这里所指的“语言”是指使用规定格式和语法的代码。
80 4
聊聊Java设计模式-解释器模式
|
6月前
|
设计模式 Go 开发工具
Golang设计模式——18解释器模式
Golang设计模式——18解释器模式
50 0
Golang设计模式——18解释器模式

热门文章

最新文章

  • 1
    C++一分钟之-设计模式:工厂模式与抽象工厂
    42
  • 2
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    46
  • 3
    C++一分钟之-C++中的设计模式:单例模式
    54
  • 4
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    38
  • 5
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    62
  • 6
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    57
  • 7
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    41
  • 8
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    50
  • 9
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    106
  • 10
    Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
    78