Java實現月餅的制作、下單和售賣功能
本文導讀
中秋節(jié)是中國民間的傳統(tǒng)節(jié)日,中秋節(jié)源自天象崇拜由上古時代秋夕祭月演變而來。中秋節(jié)自古便有祭月、賞月、吃月餅等民俗,流傳至今,經久不息。
說到月餅,我們現在吃的都是工廠、小作坊、自己家里制作,在電商平臺售賣或者有一些營銷活動贈送,我們來看看Java是怎么制作月餅的,我們是否可以在代碼實現一個月餅售賣的架構設計和設計模式。
借此機會,我們用Lambda實現一遍月餅制作,下單,售賣的開發(fā)設計模式,主要有制作月餅的工廠模式、
一、使用工廠模式制作月餅
設計模式是在大量的實踐中總結和理論化之后優(yōu)選的代碼結構、編程風格、以及解決問題的思維方式。使用工廠模式,我們就無需向消費者們暴露,我們的月餅(實例化月餅對象)的制作邏輯,就能完成月餅的制作。
1、使用工廠創(chuàng)建月餅實例
我們需要一個月餅工廠(MoonCakeFactory)或者叫月餅小作坊,在工廠里我們可以創(chuàng)建一個map 將產品名映射到對應的構造函數中,提供一個像工廠模式一樣,利用map來實例化不同對象。
/** * 一個簡單的月餅制作工廠 * @author XiaoMing */ public class MoonCakeFactory { /** * 我們可以創(chuàng)建一個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)的時候,就可以獲取到一個實例化的對象,不需要我們在使用的地方創(chuàng)建,將工廠定義為靜態(tài)方法是一個常用技巧,稱為靜態(tài)工廠,不需要創(chuàng)建方法來實例化對象,將實例化對象和創(chuàng)建方法解耦。
總結一下,工廠模式是用一個專業(yè)類(工廠類)來負責一種產品的對象創(chuàng)建。這樣做的好處是,1、把對象的創(chuàng)建和使用分開;2、將生產過程集中后,便于集中管理(增刪改);3、當實體類有變動時,使用者不需要再去修改代碼。
二、使用策略模式限制購買月餅類型
一個禮盒中有很多類型的月餅,有些餡并不我待見,博主曾經吃過一個咖啡餡月餅,這里面我們把奇奇怪怪的餡扣除去。校驗是否為有效訂單,設置該策略不允許咖啡餡月餅和榴蓮餡的下單
1、實戰(zhàn)代碼
策略模式可以理解為一種通過算法解決一類問題的通用方案,策略模式包括該算法的接口,一個或多個接口的實現邏輯,以及策略對象,下面我們用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、策略模式剖析
策略模式需要做的就是當請求進來時候,同一個入口讓他根據這個人請求的行為去執(zhí)行其中某一個類中的方法。
策略接口的定義,通常包含兩個方法:獲取策略類型的方法和處理策略業(yè)務邏輯的方法。策略接口的實現,每種支付類都實現了上述接口(基于接口而非實現編程),這樣我們可以靈活的替換不同的支付方式(上文代碼段就是使用lambda表達式實現的)。
接口只負責業(yè)務策略的定義,每個策略的具體實現單獨放在實現Impl中,我們可以使用工廠類 Factory 只負責獲取具體實現類,而具體調用代碼則負責業(yè)務邏輯的編排。這些實現用到了面向接口而非實現編程,滿足了職責單一、開閉原則,從而達到了功能上的高內聚低耦合、提高了可維護性、擴展性以及代碼的可讀性。
三、模板方法模式設計月餅的優(yōu)惠決策
我們購買月餅在電商業(yè)務中有很多優(yōu)惠信息,例如紅包、平臺券、商家券、滿減、秒殺活動等等, 如果每個優(yōu)惠寫一個方法那么就不方便閱讀和管理,我們可以用這種方式將代碼擴展性做的很好假設為下單主流程,我們主要關注 優(yōu)惠決策與核銷->優(yōu)惠信息落庫,這幾個步驟。
1、使用模板方法實現優(yōu)惠活動
讓我們從模板方法模式設計月餅的優(yōu)惠決策的例子著手,看看這個模式是如何工作的。
/** * 假設為下單主流程 * 我們主要關注 優(yōu)惠決策與核銷->優(yōu)惠信息落庫,這幾個步驟 */ public void submitOrder(List<OrderInfo> orderList) { // ... // 優(yōu)惠決策與核銷 writeOff(orderList, couponInfos -> { // 將優(yōu)惠信息落庫 transaction(orderList); }); // ... } /** * 我們購買月餅在,電商業(yè)務中有很多優(yōu)惠信息,例如紅包、平臺券、商家券、滿減、秒殺活動等等 * 如果每個優(yōu)惠寫一個方法那么就不方便閱讀和管理,我們可以用這種方式將代碼擴展性做的很好 */ public void writeOff(List<OrderInfo> orderList, Consumer<List<CouponInfo>> consumer) { // 每個優(yōu)惠信息,由自己的實現類實現 List<CouponInfo> couponInfos = consume(orderList); // 此處將結果保存 consumer.accept(couponInfos); } /** * 每個優(yōu)惠信息自己實現 ServiceImpl */ private List<CouponInfo> consume(List<OrderInfo> orderList) { List<CouponInfo> couponInfos = new ArrayList<>(); // 核銷后返回信息(實現業(yè)務邏輯) // ... return couponInfos; } /** * 將優(yōu)惠信息落庫 */ private static void transaction(List<OrderInfo> orderInfos) { }
2、模板方法剖析
模板方法模式,如果你需要采用某個算法的框架,同時又希望有一定的靈是活度,能對它的某些部分進行改進,那么采用模板方法設計模式是比較通用的方案。這樣講有些抽象。換句話說,模板方法模式在你希望使用這個算法,但是需要對其中的某些行進行改進,才能達到希望的效果時是非常有用的。
優(yōu)點,1、提高代碼復用性,可以將相同部分的代碼放在抽象的父類中;2、提高了拓展性,將不同的代碼放入不同的子類中,通過對子類的擴展增加新的行為;3、實現了反向控制,通過一個父類調用其子類的操作,通過對子類的擴展增加新的行為。
缺點,1、引入了抽象類,每一個不同的實現都需要一個子類來實現,導致類的個數增加,從而增加了系統(tǒng)實現的復雜度。
場景,1、一次性實現一個算法的不變的部分,并將可變的行為留給子類來實現;2、各子類中公共的行為應被提取出來并集中到一個公共父類中以避免代碼重復。
總結
借此中秋節(jié)機會,我們實現一個月餅售賣的設計模式。主要使用了Lambda和設計模式的思想,實現月餅制作的工廠模式,下單的策略模式校驗,優(yōu)惠券操作的模板方法模式的開發(fā)。
設計模式是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 項目中合理的運用設計模式可以完美的解決很多問題,每種模式在現在中都有相應的原理來與之對應,每一個模式描述了一個在我們周圍不斷重復發(fā)生的問題,以及該問題的核心解決方案,這也是它能被廣泛應用的原因。
到此這篇關于Java實現月餅的制作、下單和售賣的文章就介紹到這了,更多相關Java月餅內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java實現TCP/IP協(xié)議的收發(fā)數據(服務端)代碼實例
這篇文章主要介紹了Java實現TCP/IP協(xié)議的收發(fā)數據(服務端)代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-11-11Spring實戰(zhàn)之使用Expression接口進行表達式求值操作示例
這篇文章主要介紹了Spring實戰(zhàn)之使用Expression接口進行表達式求值操作,結合實例形式分析了Spring操作Expression接口實現表達式運算的操作技巧與相關注意事項,需要的朋友可以參考下2019-12-12HTTP 415錯誤-Unsupported media type詳解
這篇文章主要介紹了HTTP 415錯誤-Unsupported media type詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下2021-08-08