SpringBoot?模板模式實現優(yōu)惠券邏輯的示例代碼
一、計算邏輯的類結構圖

在這張圖里,頂層接口 RuleTemplate 定義了 calculate 方法,抽象模板類 AbstractRuleTemplate 將通用的模板計算邏輯在 calculate 方法中實現,同時它還定義了一個抽象方法 calculateNewPrice 作為子類的擴展點。各個具體的優(yōu)惠計算類通過繼承 AbstractRuleTemplate,并實現 calculateNewPrice 來編寫自己的優(yōu)惠計算方式。
二、代碼實現
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=對應門店下商品總價
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;
}
// 子類中實現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的錢數
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)惠券結算
// 這里通過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);
}到此這篇關于SpringBoot 模板模式實現優(yōu)惠券邏輯的文章就介紹到這了,更多相關SpringBoot 優(yōu)惠券邏輯內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot CountDownLatch多任務并行處理的實現方法
本篇文章主要介紹了SpringBoot CountDownLatch多任務并行處理的實現方法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-04-04
實例詳解Spring Boot實戰(zhàn)之Redis緩存登錄驗證碼
本章簡單介紹redis的配置及使用方法,本文示例代碼在前面代碼的基礎上進行修改添加,實現了使用redis進行緩存驗證碼,以及校驗驗證碼的過程。感興趣的的朋友一起看看吧2017-08-08

