Java实现月饼的制作、下单和售卖功能

 更新时间:2022年09月05日 11:51:37   作者:小明java问道之路  
这篇文章主要介绍了Java实现月饼的制作、下单和售卖,借此机会,我们用Lambda实现一遍月饼制作,下单,售卖的开发设计模式,主要有制作月饼的工厂模式,结合实例代码给大家介绍的非常详细,需要的朋友可以参考下

本文导读

中秋节是中国民间的传统节日,中秋节源自天象崇拜由上古时代秋夕祭月演变而来。中秋节自古便有祭月、赏月、吃月饼等民俗,流传至今,经久不息。

说到月饼,我们现在吃的都是工厂、小作坊、自己家里制作,在电商平台售卖或者有一些营销活动赠送,我们来看看Java是怎么制作月饼的,我们是否可以在代码实现一个月饼售卖的架构设计和设计模式。

借此机会,我们用Lambda实现一遍月饼制作,下单,售卖的开发设计模式,主要有制作月饼的工厂模式、

一、使用工厂模式制作月饼

设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思维方式。使用工厂模式,我们就无需向消费者们暴露,我们的月饼(实例化月饼对象)的制作逻辑,就能完成月饼的制作。

1、使用工厂创建月饼实例

我们需要一个月饼工厂(MoonCakeFactory)或者叫月饼小作坊,在工厂里我们可以创建一个map 将产品名映射到对应的构造函数中,提供一个像工厂模式一样,利用map来实例化不同对象。

/**
 * 一个简单的月饼制作工厂
 * @author XiaoMing
 */
public class MoonCakeFactory {
    /**
     * 我们可以创建一个map 将产品名映射到对应的构造函数中
     */
    final static Map<String, Supplier<MoonCakeInfo>> map = new HashMap<>();
 
    static {
        // 五仁的,我的最爱
        map.put("wuRen", WuRenMoonCakeInfo::new);
        // 豆沙
        map.put("redBeanPaste", RedBeanPasteMoonCakeInfo::new);
        // 枣泥
        map.put("jujubePaste", JujubePasteMoonCakeInfo::new);
        // 蛋黄的
        map.put("eggYolk", EggYolkMoonCakeInfo::new);
    }
 
    /**
     * 像工厂模式一样,利用map来实例化不同对象
     *
     * @param moonCakeType 月饼类型
     */
    public static MoonCakeInfo createMoonCake(String moonCakeType) {
        // 获取月饼供应商
        Supplier<MoonCakeInfo> moonCakeInfoSupplier = map.get(moonCakeType);
        if (null != moonCakeInfoSupplier) {
            return moonCakeInfoSupplier.get();
        }
        throw new IllegalArgumentException("No such MoonCakeInfo" + moonCakeType);
    }
}
 
/**
 * @author XiaoMing
 */
public class WuRenMoonCakeInfo extends MoonCakeInfo {
    private String wuRen;
    public String getWuRen() { return wuRen; }
    public void setWuRen(String wuRen) { this.wuRen = wuRen; }
}

2、工厂模式剖析 

现在我们就可以试着拿到对应的,实例化的月饼对象了

WuRenMoonCakeInfo wuRen = (WuRenMoonCakeInfo) createMoonCake("wuRen");

我们看完了这个例子,现在思考内部的问题,这么做有什么好处?为什么createMoonCake是一个static的方法?

我们制作月饼有很多馅,除了馅我们还可以取对应馅(moonCakeType)的时候,就可以获取到一个实例化的对象,不需要我们在使用的地方创建,将工厂定义为静态方法是一个常用技巧,称为静态工厂,不需要创建方法来实例化对象,将实例化对象和创建方法解耦。

总结一下,工厂模式是用一个专业类(工厂类)来负责一种产品的对象创建。这样做的好处是,1、把对象的创建和使用分开;2、将生产过程集中后,便于集中管理(增删改);3、当实体类有变动时,使用者不需要再去修改代码。

二、使用策略模式限制购买月饼类型

一个礼盒中有很多类型的月饼,有些馅并不我待见,博主曾经吃过一个咖啡馅月饼,这里面我们把奇奇怪怪的馅扣除去。校验是否为有效订单,设置该策略不允许咖啡馅月饼和榴莲馅的下单

1、实战代码

策略模式可以理解为一种通过算法解决一类问题的通用方案,策略模式包括该算法的接口,一个或多个接口的实现逻辑,以及策略对象,下面我们用lambda表达式实现,Validator 相当于一个中转站,strategy.validatorOrder(orderType);可以通过下属lambda实现,也可以通过实现类,继承Strategy 接口实现

    /**
     * 假设为下单主流程
     * 我们主要关注 策略模式下订单类型的校验,这几个步骤
     */
    public void submitOrder(OrderInfo orderInfo) {
        // ...
        // 校验是否为有效订单,设置该策略不允许咖啡馅月饼和榴莲馅的下单
        Validator v1 = new Validator(orderType -> !orderType.equals("Coffee") || !orderType.equals("Durian"));
        v1.validatorOrder(orderInfo.getOrderType());
        // ...
    }
 
 
/**
 * @author XiaoMing
 */
public class Validator {
    private Strategy strategy;
 
    public Validator(Strategy strategy) {
        this.strategy = strategy;
    }
 
    public boolean validatorOrder(String orderType) {
        return strategy.validatorOrder(orderType);
    }
}
 
 
/**
 * @author XiaoMing
 */
public interface Strategy {
    /**
     * 函数式接口,通过调用 Validator时实现
     */
    boolean validatorOrder(String orderType);
}

 一般我们也可以使用实现类实现

/**
 * @author xiaoming
 * @date 2022/8/27-10:33
 */
public class RealOrderImpl implements Strategy {
    @Override
    public boolean validatorOrder(String orderType) {
        System.out.println("real");
        return orderType.equals("real");
    }
}
 
public class O2OOrderImpl implements Strategy {
    @Override
    public boolean validatorOrder(String orderType) {
        System.out.println("O2O");
        return orderType.equals("O2O");
    }
}

策略模式类图: 

2、策略模式剖析

策略模式需要做的就是当请求进来时候,同一个入口让他根据这个人请求的行为去执行其中某一个类中的方法。

策略接口的定义,通常包含两个方法:获取策略类型的方法和处理策略业务逻辑的方法。策略接口的实现,每种支付类都实现了上述接口(基于接口而非实现编程),这样我们可以灵活的替换不同的支付方式(上文代码段就是使用lambda表达式实现的)。

接口只负责业务策略的定义,每个策略的具体实现单独放在实现Impl中,我们可以使用工厂类 Factory 只负责获取具体实现类,而具体调用代码则负责业务逻辑的编排。这些实现用到了面向接口而非实现编程,满足了职责单一、开闭原则,从而达到了功能上的高内聚低耦合、提高了可维护性、扩展性以及代码的可读性。

三、模板方法模式设计月饼的优惠决策

我们购买月饼在电商业务中有很多优惠信息,例如红包、平台券、商家券、满减、秒杀活动等等, 如果每个优惠写一个方法那么就不方便阅读和管理,我们可以用这种方式将代码扩展性做的很好假设为下单主流程,我们主要关注 优惠决策与核销->优惠信息落库,这几个步骤。

1、使用模板方法实现优惠活动

让我们从模板方法模式设计月饼的优惠决策的例子着手,看看这个模式是如何工作的。

    /**
     * 假设为下单主流程
     * 我们主要关注 优惠决策与核销->优惠信息落库,这几个步骤
     */
    public void submitOrder(List<OrderInfo> orderList) {
        // ...
        // 优惠决策与核销
        writeOff(orderList, couponInfos -> {
            // 将优惠信息落库
            transaction(orderList);
        });
        // ...
    }
 
 
    /**
     * 我们购买月饼在,电商业务中有很多优惠信息,例如红包、平台券、商家券、满减、秒杀活动等等
     * 如果每个优惠写一个方法那么就不方便阅读和管理,我们可以用这种方式将代码扩展性做的很好
     */
    public void writeOff(List<OrderInfo> orderList, Consumer<List<CouponInfo>> consumer) {
        // 每个优惠信息,由自己的实现类实现
        List<CouponInfo> couponInfos = consume(orderList);
 
        // 此处将结果保存
        consumer.accept(couponInfos);
    }

    /**
     * 每个优惠信息自己实现 ServiceImpl
     */
    private List<CouponInfo> consume(List<OrderInfo> orderList) {
        List<CouponInfo> couponInfos = new ArrayList<>();
        // 核销后返回信息(实现业务逻辑)
        // ...
        return couponInfos;
    }
 
 
    /**
     * 将优惠信息落库
     */
    private static void transaction(List<OrderInfo> orderInfos) {
 
    }

2、模板方法剖析

模板方法模式,如果你需要采用某个算法的框架,同时又希望有一定的灵是活度,能对它的某些部分进行改进,那么采用模板方法设计模式是比较通用的方案。这样讲有些抽象。换句话说,模板方法模式在你希望使用这个算法,但是需要对其中的某些行进行改进,才能达到希望的效果时是非常有用的。  

优点,1、提高代码复用性,可以将相同部分的代码放在抽象的父类中;2、提高了拓展性,将不同的代码放入不同的子类中,通过对子类的扩展增加新的行为;3、实现了反向控制,通过一个父类调用其子类的操作,通过对子类的扩展增加新的行为。

缺点,1、引入了抽象类,每一个不同的实现都需要一个子类来实现,导致类的个数增加,从而增加了系统实现的复杂度。

场景,1、一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现;2、各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。

总结

借此中秋节机会,我们实现一个月饼售卖的设计模式。主要使用了Lambda和设计模式的思想,实现月饼制作的工厂模式,下单的策略模式校验,优惠券操作的模板方法模式的开发。

设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。

到此这篇关于Java实现月饼的制作、下单和售卖的文章就介绍到这了,更多相关Java月饼内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • 较详细的JNI简介

    较详细的JNI简介

    JNI是本地语言编程接口。它允许运行在JVM中的Java代码和用C、C++或汇编写的本地代码相互操作。下面通过本文给大家分享JNI简介,感兴趣的朋友一起看看吧
    2017-10-10
  • maven混淆打包的实现步骤

    maven混淆打包的实现步骤

    本文主要介绍了maven混淆打包的实现步骤,包含了Maven项目混淆、瘦身、打包exe这几个方面,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • Hibernate缓存机制实例代码解析

    Hibernate缓存机制实例代码解析

    这篇文章主要介绍了Hibernate缓存机制实例代码解析,介绍了查询缓存,一级二级缓存等内容,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • Java使用递归复制文件夹及文件夹

    Java使用递归复制文件夹及文件夹

    这篇文章主要介绍了Java使用递归复制文件夹及文件夹,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • SpringBoot实现无限级评论回复的项目实践

    SpringBoot实现无限级评论回复的项目实践

    本文主要介绍了SpringBoot实现无限级评论回复的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • Java实现TCP/IP协议的收发数据(服务端)代码实例

    Java实现TCP/IP协议的收发数据(服务端)代码实例

    这篇文章主要介绍了Java实现TCP/IP协议的收发数据(服务端)代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Spring实战之使用Expression接口进行表达式求值操作示例

    Spring实战之使用Expression接口进行表达式求值操作示例

    这篇文章主要介绍了Spring实战之使用Expression接口进行表达式求值操作,结合实例形式分析了Spring操作Expression接口实现表达式运算的操作技巧与相关注意事项,需要的朋友可以参考下
    2019-12-12
  • HTTP 415错误-Unsupported media type详解

    HTTP 415错误-Unsupported media type详解

    这篇文章主要介绍了HTTP 415错误-Unsupported media type详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • java实现ArrayList根据存储对象排序功能示例

    java实现ArrayList根据存储对象排序功能示例

    这篇文章主要介绍了java实现ArrayList根据存储对象排序功能,结合实例形式分析了java针对ArrayList的相关运算、排序操作技巧,需要的朋友可以参考下
    2018-01-01
  • Java 8 新特性终极版指南详解

    Java 8 新特性终极版指南详解

    Java 8已经公布有一段时间了,种种迹象表明Java 8是一个有重大改变的发行版。本文给大家介绍Java 8 新特性终极版指南详解,需要的朋友参考下
    2016-03-03

最新评论