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;
}
}