行为性模式-策略模式
策略模式可以解决大量if…else,用来封装同一种业务功能的不同算法实现。下面是通过策略模式用来封装商品优惠卷服务(满减、折扣、直减、n元购)
技术点
使用泛型将原来的传参由4个变为两个,封装方法
面向过程实现
public double discountAmount(int type, double typeContent, double skuPrice, double typeExt) {
// 直减
if (1 == type) {
return skuPrice - typeContent;
}
// 满减
if (2 == type) {
if (skuPrice < typeExt) {
return skuPrice;
}
return skuPrice - typeContent;
}
// n元购
if (3 == type) {
return typeContent;
}
// 折扣
if (4 == type) {
return typeContent * skuPrice;
}
return 0D;
}
策略模式封装实现
接口 ICouponDiscount
public interface ICouponDiscount<T> {
BigDecimal discountAmount(T couponInfo,BigDecimal skuPrice);
}
实现类
满减
public class MJCouponDiscount implements ICouponDiscount<Map<String, String>> {
@Override
public BigDecimal discountAmount(Map<String, String> couponInfo, BigDecimal skuPrice) {
String x = couponInfo.get("x");
String t = couponInfo.get("t");
// 如果商品价钱小于满减价钱,直接返回原价
if (skuPrice.compareTo(new BigDecimal(x)) < 0) {
return skuPrice;
}
BigDecimal discountAmount = skuPrice.subtract(new BigDecimal(t));
// 如果满减后的金额小于0元,则满减后的金额为1元
if (discountAmount.compareTo(BigDecimal.ZERO) < 1) {
return BigDecimal.ONE;
}
return discountAmount;
}
}
n元购
public class NYGCouponDiscount implements ICouponDiscount<Double> {
@Override
public BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) {
return new BigDecimal(couponInfo);
}
}
直减
public class ZJCouponDiscount implements ICouponDiscount<Double> {
@Override
public BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) {
BigDecimal discountAmount = skuPrice.subtract(new BigDecimal(couponInfo));
if (discountAmount.compareTo(BigDecimal.ZERO) < 1) {
return BigDecimal.ONE;
}
return discountAmount;
}
}
折扣
public class ZKCouponDiscount implements ICouponDiscount<Double> {
public BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) {
BigDecimal bigDecimal = skuPrice.multiply(new BigDecimal(couponInfo)).setScale(2,BigDecimal.ROUND_UP);
if (bigDecimal.compareTo(BigDecimal.ZERO) < 1) {
return BigDecimal.ONE;
}
return bigDecimal;
}
}
策略控制类
public class Context<T> {
private ICouponDiscount<T> iCouponDiscount;
public Context(ICouponDiscount<T> iCouponDiscount) {
this.iCouponDiscount = iCouponDiscount;
}
public BigDecimal discountAmount(T couponInfo, BigDecimal skuPrice) {
return iCouponDiscount.discountAmount(couponInfo, skuPrice);
}
}
测试
public void testMJ() {
// 测试满减
Context context = new Context(new MJCouponDiscount());
Map<String, String> map = new HashMap<>();
map.put("x", "500");
map.put("t", "20");
BigDecimal discountAmount = context.discountAmount(map, new BigDecimal(600d));
logger.info("满减后的商品价钱是:{}", discountAmount);
}
@Test
public void testZJ() {
// 测试直减
Context context = new Context(new ZJCouponDiscount());
BigDecimal discountAmount = context.discountAmount(40D, new BigDecimal(600d));
logger.info("直减后的商品价钱是:{}", discountAmount);
}
@Test
public void testZK() {
// 测试折扣
Context context = new Context(new ZKCouponDiscount());
BigDecimal discountAmount = context.discountAmount(0.89D, new BigDecimal(600d));
logger.info("折扣后的商品价钱是:{}", discountAmount);
}
@Test
public void testNYG() {
// 测试n元购
Context context = new Context(new NYGCouponDiscount());
BigDecimal discountAmount = context.discountAmount(517D, new BigDecimal(600d));
logger.info("n元购的商品价钱是:{}", discountAmount);
}