目录
优惠券系统
优惠券A:
满多少金额使用 (满m减X元)
优惠券B:
无门槛使用 (减X元)
设计思想:
合并AB,简化逻辑:未满金额0元 满金额的X元。 (B就是X=0)
设计:
属性:面值X
方法:传入金额计算当前面值
代码:
/**
* 优惠券
*/
public class Coupon {
private String couponId;
private double needPay;
private double money;
private double value;
/**
* 无门槛优惠券
*
* @param value
* @param money
*/
public Coupon(String couponId, double value, double money) {
this(couponId, value, 0, money);
}
/**
* 满多少减多少优惠券
*
* @param value 面值
* @param money 需要支付多少金额生效
* @param money 传入的金融
*/
public Coupon(String couponId, double value, double needPay, double money) {
this.couponId = couponId;
this.value = value;
this.needPay = needPay;
this.money = money;
}
public double getBenefit() {
return money >= needPay ? value : 0;
}
}
会员卡系统
需求
在优惠券已经首先的情况的下,产品又出了 会员卡系统,可以选择使用会员卡或者优惠券
会员卡系统:分三种
A会员卡:储值卡 - 多少金额有限使用储值卡
B会员卡:折扣卡 - 可以直接打折 最终优惠金额
C会员卡:储值折扣卡 - 先打折,打折之后使用卡里的钱
在优惠券的基础上,我们可以选择使用会员卡或者优惠券
感受
(当然储值卡钱会对应的减掉 这个就后端处理就好 前端我们只需要当前是面值)
完了,之前写好的推翻重来?
感觉完全不能接受啊
我们理一下思路,优惠券里面有属性面值X。
A会员卡中 储值卡其实也是一种面值
B会员卡优惠的金额也是储值卡的面值
C会员卡储值也是储值卡的面值
那么继续,优化下会员卡的计算方式:
A会员卡中,传入金额为m,储值n大于m,则面值为m,储值n小于等于m,则为面值为n;
B会员卡中,传入金额为m,折扣Z,面值为m-mz;
C会员卡中,传入金额为m,折扣Z,储值n,总价为mz;
储值n大于mz,则储值面值为mz;储值n小于等于mz,则为储值面值为n;
当然优惠部分也是该会员卡的面值 即 (m-mz)+ mz = m 和传入金额一样,即使全部抵扣 或者是储值n小于等于mz, ( m-mz)+ n
OK 我们会员卡就变成一张特殊的优惠券;这样就把会员卡和优惠券等同处理可以复用之前的逻辑,减肥了代码维护内容。
但是这样概念较为抽象,优化一下,抽离一个优惠概念
代码:
/**
* 优惠模型
*/
public interface Benefit {
/**
* 获取优惠值
*
* @param money 优惠的价格 即优化的价值 或者说面额
* @return
*/
double getBenefitValue(double money);
}
/**
* 优惠券
*/
public class Coupon implements Benefit {
private String couponId;
/**
* 满多少
*/
private double needPay;
/**
* 减多少
*/
private double value;
@Override
public double getBenefitValue(double money) {
return money >= needPay ? value : 0;
}
}
/**
* 会员卡
*/
public class VipCard implements Benefit {
private String vipCardId;
/**
* 折扣
*/
private double discount;
/**
* 储值
*/
private double storeValue;
/**
* 卡类型
*/
private int vipCardType;
/**
* 储值卡
*/
private static final int TYPE_STORE_VALUE = 0;
/**
* 折扣卡
*/
private static final int TYPE_DISCOUNT = 1;
/**
* 储值折扣卡
*/
private static final int TYPE_STORE_VALUE_DISCOUNT = 2;
@Override
public double getBenefitValue(double money) {
switch (vipCardType) {
case TYPE_STORE_VALUE:
//A会员卡中,传入金额为m,储值n大于m,则面值为m,储值n小于等于m,则为面值为n;
return money >= storeValue ? storeValue : money;
case TYPE_DISCOUNT:
//B会员卡中,传入金额为m,折扣Z,面值为m-mz
return money - money * discount;
case TYPE_STORE_VALUE_DISCOUNT:
/**
* 传入金额为m,折扣Z,储值n,总价为mz;
* 储值n大于mz,则储值面值为mz;
* 储值n小于等于mz,则为储值面值为n;
* 当然优惠部分也是该会员卡的面值 即 (m-mz)+ mz = m 和传入金额一样,即使全部抵扣 或者是储值n小于等于mz, ( m-mz)+ n
*/
double allMoney = money * discount;
//这里全部钱都被优惠掉了 储值也算优化
if (storeValue > allMoney) {
return money;
}
return money - allMoney + storeValue;
default:
return 0;
}
}
}
结果:
这里的话会员卡和优惠券我们已经抽离成为同一概念,这样也可以在列表共同选择优惠了。但是目前来看对该项目是基本够用了,但是接下来是否能经得起接下来产品需求对推敲呢,未完待续...