SpringBoot?模板模式實現(xiàn)優(yōu)惠券邏輯的示例代碼
一、計算邏輯的類結(jié)構(gòu)圖
在這張圖里,頂層接口 RuleTemplate 定義了 calculate 方法,抽象模板類 AbstractRuleTemplate 將通用的模板計算邏輯在 calculate 方法中實現(xiàn),同時它還定義了一個抽象方法 calculateNewPrice 作為子類的擴展點。各個具體的優(yōu)惠計算類通過繼承 AbstractRuleTemplate,并實現(xiàn) calculateNewPrice 來編寫自己的優(yōu)惠計算方式。
二、代碼實現(xiàn)
1、RuleTemplate.java
public interface RuleTemplate { // 計算優(yōu)惠券 ShoppingCart calculate(ShoppingCart settlement); }
2、AbstractRuleTemplate.java
public ShoppingCart calculate(ShoppingCart order) { // 獲取訂單總價 Long orderTotalAmount = getTotalPrice(order.getProducts()); // 獲取以shopId為維度的總價統(tǒng)計 Map<Long, Long> sumAmount = getTotalPriceGroupByShop(order.getProducts()); CouponTemplateInfo template = order.getCouponInfos().get(0).getTemplate(); // 最低消費限制 Long threshold = template.getRule().getDiscount().getThreshold(); // 優(yōu)惠金額或者打折比例 Long quota = template.getRule().getDiscount().getQuota(); // 如果優(yōu)惠券未指定shopId,則shopTotalAmount=orderTotalAmount // 如果指定了shopId,則shopTotalAmount=對應(yīng)門店下商品總價 Long shopId = template.getShopId(); Long shopTotalAmount = (shopId == null) ? orderTotalAmount : sumAmount.get(shopId); // 如果不符合優(yōu)惠券使用標準, 則直接按原價走,不使用優(yōu)惠券 if (shopTotalAmount == null || shopTotalAmount < threshold) { log.debug("Totals of amount not meet"); order.setCost(orderTotalAmount); order.setCouponInfos(Collections.emptyList()); return order; } // 子類中實現(xiàn)calculateNewPrice計算新的價格 Long newCost = calculateNewPrice(orderTotalAmount, shopTotalAmount, quota); if (newCost < minCost()) { newCost = minCost(); } order.setCost(newCost); log.debug("original price={}, new price={}", orderTotalAmount, newCost); return order; }
3、子類
MoneyOffTemplate.java
@Slf4j @Component public class MoneyOffTemplate extends AbstractRuleTemplate implements RuleTemplate { @Override protected Long calculateNewPrice(Long totalAmount, Long shopAmount, Long quota) { // benefitAmount是扣減的價格 // 如果當前門店的商品總價<quota,那么最多只能扣減shopAmount的錢數(shù) Long benefitAmount = shopAmount < quota ? shopAmount : quota; return totalAmount - benefitAmount; } }
4、工廠類
CouponTemplateFactory.java
@Component @Slf4j public class CouponTemplateFactory { @Autowired private MoneyOffTemplate moneyOffTemplate; @Autowired private DiscountTemplate discountTemplate; @Autowired private RandomReductionTemplate randomReductionTemplate; @Autowired private LonelyNightTemplate lonelyNightTemplate; @Autowired private DummyTemplate dummyTemplate; @Autowired private AntiPauTemplate antiPauTemplate; public RuleTemplate getTemplate(ShoppingCart order) { // 不使用優(yōu)惠券 if (CollectionUtils.isEmpty(order.getCouponInfos())) { // dummy模板直接返回原價,不進行優(yōu)惠計算 return dummyTemplate; } // 獲取優(yōu)惠券的類別 // 目前每個訂單只支持單張優(yōu)惠券 CouponTemplateInfo template = order.getCouponInfos().get(0).getTemplate(); CouponType category = CouponType.convert(template.getType()); switch (category) { // 訂單滿減券 case MONEY_OFF: return moneyOffTemplate; // 隨機立減券 case RANDOM_DISCOUNT: return randomReductionTemplate; // 午夜下單優(yōu)惠翻倍 case LONELY_NIGHT_MONEY_OFF: return lonelyNightTemplate; // 打折券 case DISCOUNT: return discountTemplate; case ANTI_PUA: return antiPauTemplate; // 未知類型的券模板 default: return dummyTemplate; } } }
5、使用
CouponCalculationServiceImpl.java
@Autowired private CouponTemplateFactory couponProcessorFactory; // 優(yōu)惠券結(jié)算 // 這里通過Factory類決定使用哪個底層Rule,底層規(guī)則對上層透明 @Override public ShoppingCart calculateOrderPrice(@RequestBody ShoppingCart cart) { log.info("calculate order price: {}", JSON.toJSONString(cart)); RuleTemplate ruleTemplate = couponProcessorFactory.getTemplate(cart); return ruleTemplate.calculate(cart); }
到此這篇關(guān)于SpringBoot 模板模式實現(xiàn)優(yōu)惠券邏輯的文章就介紹到這了,更多相關(guān)SpringBoot 優(yōu)惠券邏輯內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis批量插入大量數(shù)據(jù)的最優(yōu)方式總結(jié)
批量插入功能是我們?nèi)粘9ぷ髦斜容^常見的業(yè)務(wù)功能之一,下面這篇文章主要給大家總結(jié)介紹了關(guān)于Mybatis批量插入大量數(shù)據(jù)的幾種最優(yōu)方式,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-03-03SpringBoot CountDownLatch多任務(wù)并行處理的實現(xiàn)方法
本篇文章主要介紹了SpringBoot CountDownLatch多任務(wù)并行處理的實現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-04-04實例詳解Spring Boot實戰(zhàn)之Redis緩存登錄驗證碼
本章簡單介紹redis的配置及使用方法,本文示例代碼在前面代碼的基礎(chǔ)上進行修改添加,實現(xiàn)了使用redis進行緩存驗證碼,以及校驗驗證碼的過程。感興趣的的朋友一起看看吧2017-08-08