装饰器模式-实现电商的优惠活动价格计算

1、案例

1、商品有基本价格
2、可以使用优惠券和红包两种优惠活动
3、基于装饰器模式,实现价格的计算和扩展。

2、实现代码-业务逻辑

2.1、商品类
import java.math.BigDecimal;
import java.util.Map;

/**
 * 商品实体类
 */
public class Merchandise {
    private String sku;
    private String name;
    private BigDecimal price;
    private Map<PromotionType, SupportPromotions> supportPromotions;

    public String getSku() {
        return sku;
    }

    public void setSku(String sku) {
        this.sku = sku;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public Map<PromotionType, SupportPromotions> getSupportPromotions() {
        return supportPromotions;
    }

    public void setSupportPromotions(Map<PromotionType, SupportPromotions> supportPromotions) {
        this.supportPromotions = supportPromotions;
    }
}
2.2、订单类
import java.math.BigDecimal;
import java.util.List;

/**
 * 订单实体类
 */
public class Order {
    private int id;
    private String orderNo;
    private BigDecimal totalPayMoney;
    private List<OrderDetail> list;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public BigDecimal getTotalPayMoney() {
        return totalPayMoney;
    }

    public void setTotalPayMoney(BigDecimal totalPayMoney) {
        this.totalPayMoney = totalPayMoney;
    }

    public List<OrderDetail> getList() {
        return list;
    }

    public void setList(List<OrderDetail> list) {
        this.list = list;
    }
}
2.3、订单明细类
import java.math.BigDecimal;

/**
 * 订单明细类
 */
public class OrderDetail {
    private int id;
    private int orderId;
    private Merchandise merchandise;
    private BigDecimal payMoney;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getOrderId() {
        return orderId;
    }

    public void setOrderId(int orderId) {
        this.orderId = orderId;
    }

    public Merchandise getMerchandise() {
        return merchandise;
    }

    public void setMerchandise(Merchandise merchandise) {
        this.merchandise = merchandise;
    }

    public BigDecimal getPayMoney() {
        return payMoney;
    }

    public void setPayMoney(BigDecimal payMoney) {
        this.payMoney = payMoney;
    }
}
2.4、优惠活动类型
/**
 * 优惠活动枚举
 */
public enum PromotionType {
    COUPON(1),
    REDPACKET(2),
    ;
    private int code;

    PromotionType(final int code){
        this.code = code;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }
}
2.5 优惠券类
import java.math.BigDecimal;

/**
 * 用户优惠券类
 */
public class UserCoupon {
    private int id;
    private int userId;
    private String sku;
    private BigDecimal coupon;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getSku() {
        return sku;
    }

    public void setSku(String sku) {
        this.sku = sku;
    }

    public BigDecimal getCoupon() {
        return coupon;
    }

    public void setCoupon(BigDecimal coupon) {
        this.coupon = coupon;
    }
}
2.6 红包类
import java.math.BigDecimal;

/**
 * 用户红包类
 */
public class UserRedPacket {
    private int id;
    private int userId;
    private String sku;
    private BigDecimal redPacket;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getSku() {
        return sku;
    }

    public void setSku(String sku) {
        this.sku = sku;
    }

    public BigDecimal getRedPacket() {
        return redPacket;
    }

    public void setRedPacket(BigDecimal redPacket) {
        this.redPacket = redPacket;
    }
}
2.7、商品支持的优惠活动类型
/**
 * 商品支持的优惠活动,依次计算价格
 */
public class SupportPromotions implements Cloneable {
    private int id;
    private PromotionType promotionType;
    private int priority;
    private UserCoupon userCoupon;
    private UserRedPacket userRedPacket;

    public SupportPromotions clone(){
        SupportPromotions supportPromotions = null;
        try {
            supportPromotions = (SupportPromotions) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        return supportPromotions;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public PromotionType getPromotionType() {
        return promotionType;
    }

    public void setPromotionType(PromotionType promotionType) {
        this.promotionType = promotionType;
    }

    public int getPriority() {
        return priority;
    }

    public void setPriority(int priority) {
        this.priority = priority;
    }

    public UserCoupon getUserCoupon() {
        return userCoupon;
    }

    public void setUserCoupon(UserCoupon userCoupon) {
        this.userCoupon = userCoupon;
    }

    public UserRedPacket getUserRedPacket() {
        return userRedPacket;
    }

    public void setUserRedPacket(UserRedPacket userRedPacket) {
        this.userRedPacket = userRedPacket;
    }
}

3、实现代码-装饰器

3.1、基本接口类
import java.math.BigDecimal;

/**
 * 基本接口类
 */
public interface IBaseCount {
    /**
     * 计算订单商品支付金额
     */
    BigDecimal countPayMoney(OrderDetail orderDetail);
}
3.2、基本实现类
import java.math.BigDecimal;

/**
 * 基本实现类
 */
public class BaseCount implements IBaseCount {
    @Override
    public BigDecimal countPayMoney(OrderDetail orderDetail) {
        orderDetail.setPayMoney(orderDetail.getMerchandise().getPrice());
        System.out.println("商品原单价金额为:" + orderDetail.getPayMoney());

        return orderDetail.getPayMoney();
    }
}
3.3、装饰器-基本抽象类
import java.math.BigDecimal;

/**
 * 装饰器-基本抽象类
 */
public abstract class BaseCountDecorator implements IBaseCount {
    private IBaseCount count;

    public BaseCountDecorator(IBaseCount count) {
        this.count = count;
    }

    public BigDecimal countPayMoney(OrderDetail orderDetail) {
        BigDecimal payTotalMoney = new BigDecimal(0);
        if(count != null) {
            payTotalMoney = count.countPayMoney(orderDetail);
        }

        return payTotalMoney;
    }
}
3.4、装饰器-优惠券类
import java.math.BigDecimal;

/**
 * 装饰器-优惠券实现类
 */
public class CouponDecorator extends BaseCountDecorator {

    public CouponDecorator(IBaseCount count) {
        super(count);
    }

    public BigDecimal countPayMoney(OrderDetail orderDetail){
        BigDecimal payTotalMoney = new BigDecimal(0);

        payTotalMoney = super.countPayMoney(orderDetail);
        payTotalMoney = countCouponPayMoney(orderDetail);

        return payTotalMoney;
    }

    private BigDecimal countCouponPayMoney(OrderDetail orderDetail) {
        BigDecimal coupon = orderDetail.getMerchandise().getSupportPromotions().get(PromotionType.COUPON).getUserCoupon().getCoupon();
        System.out.println("优惠券金额:" + coupon);
        orderDetail.setPayMoney(orderDetail.getPayMoney().subtract(coupon));

        return orderDetail.getPayMoney();
    }
}
3.4、装饰器-红包类
import java.math.BigDecimal;

/**
 * 装饰器-优惠券实现类
 */
public class RedPacketDecorator extends BaseCountDecorator {

    public RedPacketDecorator(IBaseCount count) {
        super(count);
    }

    public BigDecimal countPayMoney(OrderDetail orderDetail){
        BigDecimal payTotalMoney = new BigDecimal(0);

        payTotalMoney = super.countPayMoney(orderDetail);
        payTotalMoney = countCouponPayMoney(orderDetail);

        return payTotalMoney;
    }

    private BigDecimal countCouponPayMoney(OrderDetail orderDetail) {
        BigDecimal redPacket = orderDetail.getMerchandise().getSupportPromotions().get(PromotionType.REDPACKET).getUserRedPacket().getRedPacket();
        System.out.println("红包优惠金额:" + redPacket);
        orderDetail.setPayMoney(orderDetail.getPayMoney().subtract(redPacket));

        return orderDetail.getPayMoney();
    }
}
3.5、优惠活动工厂计算类
import java.math.BigDecimal;
import java.util.Map;

/**
 * 优惠活动价格计算工具类
 */
public class PromotionFactory {
    public static BigDecimal getPayMoney(OrderDetail orderDetail) {
        Map<PromotionType, SupportPromotions> supportPromotionslist = orderDetail.getMerchandise().getSupportPromotions();

        IBaseCount baseCount = new BaseCount();

        if(supportPromotionslist != null) {
            for(PromotionType type : supportPromotionslist.keySet()) {
                baseCount = protmotion(supportPromotionslist.get(type), baseCount);
            }
        }

        return baseCount.countPayMoney(orderDetail);
    }

    private static IBaseCount protmotion(SupportPromotions supportPromotions, IBaseCount baseCount){
        if(supportPromotions.getPromotionType() == PromotionType.COUPON) {
            baseCount = new CouponDecorator(baseCount);
        }
        if(supportPromotions.getPromotionType() == PromotionType.COUPON) {
            baseCount = new RedPacketDecorator(baseCount);
        }

        return baseCount;
    }
}

结果:

装饰器模式-实现电商的优惠活动价格计算

上一篇:关于订单创建的service层


下一篇:mybatis高级结果映射