【设计模式】设计模式之解释器模式

文章目录

  • 前言
  • 一、解释器模式
  • 二、最佳实践
  • 总结

前言

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

所有案例代码主要以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
    }
}

上述仅仅是一个简单的示例,实际应用中可能会更加复杂。例如,可能需要实现更多的折扣规则类型,或者添加更多的操作和函数。但是,无论怎样扩展和修改折扣系统的规则,解释器模式都可以帮助我们轻松地完成这些任务。

总结

解释器模式其实并不难,大家在学习的时候一定要在理解的基础上去写代码,不要去背代码。

你可能感兴趣的:(#,设计模式,设计模式,解释器模式,java)