Java實現(xiàn)月餅的制作、下單和售賣功能
本文導(dǎo)讀
中秋節(jié)是中國民間的傳統(tǒng)節(jié)日,中秋節(jié)源自天象崇拜由上古時代秋夕祭月演變而來。中秋節(jié)自古便有祭月、賞月、吃月餅等民俗,流傳至今,經(jīng)久不息。
說到月餅,我們現(xiàn)在吃的都是工廠、小作坊、自己家里制作,在電商平臺售賣或者有一些營銷活動贈送,我們來看看Java是怎么制作月餅的,我們是否可以在代碼實現(xiàn)一個月餅售賣的架構(gòu)設(shè)計和設(shè)計模式。
借此機(jī)會,我們用Lambda實現(xiàn)一遍月餅制作,下單,售賣的開發(fā)設(shè)計模式,主要有制作月餅的工廠模式、
一、使用工廠模式制作月餅
設(shè)計模式是在大量的實踐中總結(jié)和理論化之后優(yōu)選的代碼結(jié)構(gòu)、編程風(fēng)格、以及解決問題的思維方式。使用工廠模式,我們就無需向消費者們暴露,我們的月餅(實例化月餅對象)的制作邏輯,就能完成月餅的制作。
1、使用工廠創(chuàng)建月餅實例
我們需要一個月餅工廠(MoonCakeFactory)或者叫月餅小作坊,在工廠里我們可以創(chuàng)建一個map 將產(chǎn)品名映射到對應(yīng)的構(gòu)造函數(shù)中,提供一個像工廠模式一樣,利用map來實例化不同對象。
/**
* 一個簡單的月餅制作工廠
* @author XiaoMing
*/
public class MoonCakeFactory {
/**
* 我們可以創(chuàng)建一個map 將產(chǎn)品名映射到對應(yīng)的構(gòu)造函數(shù)中
*/
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) {
// 獲取月餅供應(yīng)商
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、工廠模式剖析
現(xiàn)在我們就可以試著拿到對應(yīng)的,實例化的月餅對象了
WuRenMoonCakeInfo wuRen = (WuRenMoonCakeInfo) createMoonCake("wuRen");

我們看完了這個例子,現(xiàn)在思考內(nèi)部的問題,這么做有什么好處?為什么createMoonCake是一個static的方法?
我們制作月餅有很多餡,除了餡我們還可以取對應(yīng)餡(moonCakeType)的時候,就可以獲取到一個實例化的對象,不需要我們在使用的地方創(chuàng)建,將工廠定義為靜態(tài)方法是一個常用技巧,稱為靜態(tài)工廠,不需要創(chuàng)建方法來實例化對象,將實例化對象和創(chuàng)建方法解耦。
總結(jié)一下,工廠模式是用一個專業(yè)類(工廠類)來負(fù)責(zé)一種產(chǎn)品的對象創(chuàng)建。這樣做的好處是,1、把對象的創(chuàng)建和使用分開;2、將生產(chǎn)過程集中后,便于集中管理(增刪改);3、當(dāng)實體類有變動時,使用者不需要再去修改代碼。
二、使用策略模式限制購買月餅類型
一個禮盒中有很多類型的月餅,有些餡并不我待見,博主曾經(jīng)吃過一個咖啡餡月餅,這里面我們把奇奇怪怪的餡扣除去。校驗是否為有效訂單,設(shè)置該策略不允許咖啡餡月餅和榴蓮餡的下單
1、實戰(zhàn)代碼
策略模式可以理解為一種通過算法解決一類問題的通用方案,策略模式包括該算法的接口,一個或多個接口的實現(xiàn)邏輯,以及策略對象,下面我們用lambda表達(dá)式實現(xiàn),Validator 相當(dāng)于一個中轉(zhuǎn)站,strategy.validatorOrder(orderType);可以通過下屬lambda實現(xiàn),也可以通過實現(xiàn)類,繼承Strategy 接口實現(xiàn)
/**
* 假設(shè)為下單主流程
* 我們主要關(guān)注 策略模式下訂單類型的校驗,這幾個步驟
*/
public void submitOrder(OrderInfo orderInfo) {
// ...
// 校驗是否為有效訂單,設(shè)置該策略不允許咖啡餡月餅和榴蓮餡的下單
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 {
/**
* 函數(shù)式接口,通過調(diào)用 Validator時實現(xiàn)
*/
boolean validatorOrder(String orderType);
}一般我們也可以使用實現(xiàn)類實現(xiàn)
/**
* @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、策略模式剖析
策略模式需要做的就是當(dāng)請求進(jìn)來時候,同一個入口讓他根據(jù)這個人請求的行為去執(zhí)行其中某一個類中的方法。
策略接口的定義,通常包含兩個方法:獲取策略類型的方法和處理策略業(yè)務(wù)邏輯的方法。策略接口的實現(xiàn),每種支付類都實現(xiàn)了上述接口(基于接口而非實現(xiàn)編程),這樣我們可以靈活的替換不同的支付方式(上文代碼段就是使用lambda表達(dá)式實現(xiàn)的)。
接口只負(fù)責(zé)業(yè)務(wù)策略的定義,每個策略的具體實現(xiàn)單獨放在實現(xiàn)Impl中,我們可以使用工廠類 Factory 只負(fù)責(zé)獲取具體實現(xiàn)類,而具體調(diào)用代碼則負(fù)責(zé)業(yè)務(wù)邏輯的編排。這些實現(xiàn)用到了面向接口而非實現(xiàn)編程,滿足了職責(zé)單一、開閉原則,從而達(dá)到了功能上的高內(nèi)聚低耦合、提高了可維護(hù)性、擴(kuò)展性以及代碼的可讀性。

三、模板方法模式設(shè)計月餅的優(yōu)惠決策
我們購買月餅在電商業(yè)務(wù)中有很多優(yōu)惠信息,例如紅包、平臺券、商家券、滿減、秒殺活動等等, 如果每個優(yōu)惠寫一個方法那么就不方便閱讀和管理,我們可以用這種方式將代碼擴(kuò)展性做的很好假設(shè)為下單主流程,我們主要關(guān)注 優(yōu)惠決策與核銷->優(yōu)惠信息落庫,這幾個步驟。
1、使用模板方法實現(xiàn)優(yōu)惠活動
讓我們從模板方法模式設(shè)計月餅的優(yōu)惠決策的例子著手,看看這個模式是如何工作的。
/**
* 假設(shè)為下單主流程
* 我們主要關(guān)注 優(yōu)惠決策與核銷->優(yōu)惠信息落庫,這幾個步驟
*/
public void submitOrder(List<OrderInfo> orderList) {
// ...
// 優(yōu)惠決策與核銷
writeOff(orderList, couponInfos -> {
// 將優(yōu)惠信息落庫
transaction(orderList);
});
// ...
}
/**
* 我們購買月餅在,電商業(yè)務(wù)中有很多優(yōu)惠信息,例如紅包、平臺券、商家券、滿減、秒殺活動等等
* 如果每個優(yōu)惠寫一個方法那么就不方便閱讀和管理,我們可以用這種方式將代碼擴(kuò)展性做的很好
*/
public void writeOff(List<OrderInfo> orderList, Consumer<List<CouponInfo>> consumer) {
// 每個優(yōu)惠信息,由自己的實現(xiàn)類實現(xiàn)
List<CouponInfo> couponInfos = consume(orderList);
// 此處將結(jié)果保存
consumer.accept(couponInfos);
}
/**
* 每個優(yōu)惠信息自己實現(xiàn) ServiceImpl
*/
private List<CouponInfo> consume(List<OrderInfo> orderList) {
List<CouponInfo> couponInfos = new ArrayList<>();
// 核銷后返回信息(實現(xiàn)業(yè)務(wù)邏輯)
// ...
return couponInfos;
}
/**
* 將優(yōu)惠信息落庫
*/
private static void transaction(List<OrderInfo> orderInfos) {
}2、模板方法剖析
模板方法模式,如果你需要采用某個算法的框架,同時又希望有一定的靈是活度,能對它的某些部分進(jìn)行改進(jìn),那么采用模板方法設(shè)計模式是比較通用的方案。這樣講有些抽象。換句話說,模板方法模式在你希望使用這個算法,但是需要對其中的某些行進(jìn)行改進(jìn),才能達(dá)到希望的效果時是非常有用的。
優(yōu)點,1、提高代碼復(fù)用性,可以將相同部分的代碼放在抽象的父類中;2、提高了拓展性,將不同的代碼放入不同的子類中,通過對子類的擴(kuò)展增加新的行為;3、實現(xiàn)了反向控制,通過一個父類調(diào)用其子類的操作,通過對子類的擴(kuò)展增加新的行為。
缺點,1、引入了抽象類,每一個不同的實現(xiàn)都需要一個子類來實現(xiàn),導(dǎo)致類的個數(shù)增加,從而增加了系統(tǒng)實現(xiàn)的復(fù)雜度。
場景,1、一次性實現(xiàn)一個算法的不變的部分,并將可變的行為留給子類來實現(xiàn);2、各子類中公共的行為應(yīng)被提取出來并集中到一個公共父類中以避免代碼重復(fù)。

總結(jié)
借此中秋節(jié)機(jī)會,我們實現(xiàn)一個月餅售賣的設(shè)計模式。主要使用了Lambda和設(shè)計模式的思想,實現(xiàn)月餅制作的工廠模式,下單的策略模式校驗,優(yōu)惠券操作的模板方法模式的開發(fā)。
設(shè)計模式是一套被反復(fù)使用、多數(shù)人知曉的、經(jīng)過分類編目的、代碼設(shè)計經(jīng)驗的總結(jié)。使用設(shè)計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 項目中合理的運用設(shè)計模式可以完美的解決很多問題,每種模式在現(xiàn)在中都有相應(yīng)的原理來與之對應(yīng),每一個模式描述了一個在我們周圍不斷重復(fù)發(fā)生的問題,以及該問題的核心解決方案,這也是它能被廣泛應(yīng)用的原因。
到此這篇關(guān)于Java實現(xiàn)月餅的制作、下單和售賣的文章就介紹到這了,更多相關(guān)Java月餅內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解spring applicationContext.xml 配置文件
本篇文章主要介紹了詳解spring applicationContext.xml 配置文件 ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02
SpringMVC框架和SpringBoot項目中控制器的響應(yīng)結(jié)果深入分析
這篇文章主要介紹了SpringMVC框架和SpringBoot項目中控制器的響應(yīng)結(jié)果,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-12-12
基于常用json框架介紹和Jackson返回結(jié)果處理方式
這篇文章主要介紹了基于常用json框架介紹和Jackson返回結(jié)果處理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09

