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;
}
}
4、啓動類
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Order order = new Order();
init(order);
for(OrderDetail orderDetail : order.getList()){
BigDecimal payMoney = PromotionFactory.getPayMoney(orderDetail);
orderDetail.setPayMoney(payMoney);
System.out.println("最終支付金額:" + orderDetail.getPayMoney());
}
}
/**
*初始化訂單
*/
private static Order init(Order order) {
Map<PromotionType, SupportPromotions> supportPromotionslist = new HashMap<PromotionType, SupportPromotions>();
SupportPromotions supportPromotions = new SupportPromotions();
supportPromotions.setPromotionType(PromotionType.COUPON);
supportPromotions.setPriority(1);
UserCoupon userCoupon= new UserCoupon();
userCoupon.setCoupon(new BigDecimal(3));
userCoupon.setSku("aaa1111");
userCoupon.setUserId(11);
supportPromotions.setUserCoupon(userCoupon);
supportPromotionslist.put(PromotionType.COUPON, supportPromotions);
SupportPromotions supportPromotions1 = supportPromotions.clone();
supportPromotions1.setPromotionType(PromotionType.REDPACKET);
supportPromotions1.setPriority(2);
UserRedPacket userRedPacket= new UserRedPacket();
userRedPacket.setId(1);
userRedPacket.setRedPacket(new BigDecimal(10));
userRedPacket.setSku("aaa1111");
userCoupon.setUserId(11);
supportPromotions1.setUserRedPacket(userRedPacket);
supportPromotionslist.put(PromotionType.REDPACKET, supportPromotions1);
Merchandise merchandise = new Merchandise();
merchandise.setSku("aaa1111");
merchandise.setName("蘋果");
merchandise.setPrice(new BigDecimal(20));
merchandise.setSupportPromotions(supportPromotionslist);
List<OrderDetail> OrderDetailList = new ArrayList<OrderDetail>();
OrderDetail orderDetail = new OrderDetail();
orderDetail.setId(1);
orderDetail.setOrderId(1111);
orderDetail.setMerchandise(merchandise);
OrderDetailList.add(orderDetail);
order.setList(OrderDetailList);
return order;
}
}