实现一个优惠券系统,实现了优惠券的扣减功能、优惠券间叠加校验、优惠券的门槛校验,同时使用策略模式对不同类型的优惠券实现金额的扣减。
代码
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 优惠券系统
*/
public class Coupon {
// 券之间的叠加规则(每种优惠券只能使用一次)
String rule = "{\"1\":[{\"id\":1,\"value\":1}], \"2\":[{\"id\":2,\"value\":1}]}";
public static void main(String[] args) {
// 定义两张优惠券
CouponEntity couponEntity1 = new CouponEntity(1, "满300减30券", 1, "{\"amount\":300}", 30);
CouponEntity couponEntity2 = new CouponEntity(2, "7折优惠券(满300)", 2, "{\"amount\":300}", 70);
List<CouponEntity> couponEntities = new ArrayList<>();
couponEntities.add(couponEntity1);
couponEntities.add(couponEntity2);
// 定义商品
Good good1 = new Good("三得利", "淘宝", 50);
Good good2 = new Good("鼠标", "淘宝", 250);
Good good3 = new Good("键盘", "天猫", 300);
List<Good> goodList = new ArrayList<>();
goodList.add(good1);
goodList.add(good2);
goodList.add(good3);
double price = count(couponEntities, goodList);
}
// 计算订单总价
public static double count(List<CouponEntity> couponEntities, List<Good> goodList) {
// 判断券组合是否合法
if (!valid(couponEntities)) {
throw new RuntimeException("券组合非法");
}
// 为了方便直接计算所有商品总和
double total = goodList.stream().mapToDouble(Good::getPrice).sum();
for (CouponEntity couponEntity : couponEntities) {
// 判断是否达到使用门槛
total = couponEntity.getPrice(total);
}
return total;
}
public static boolean valid(List<CouponEntity> couponEntities) {
Map<Integer, Long> collect = couponEntities.stream()
.collect(Collectors.groupingBy(CouponEntity::getId, Collectors.counting()));
for (int id : collect.keySet()) {
/**
* 伪代码
* 券之间的叠加规则(每种优惠券只能使用一次)
* String rule = "{\"1\":[{\"id\":1,\"value\":1}], \"2\":[{\"id\":2,\"value\":1}]}";
* ruleJson = JSON.parse(rule);
* array = ruleJson.getJSONArray(id);
* if (array == null) continue;
* for (JSON json : array) {
* if (collect.getOrDefault(json.get("id"), 0) > json.get("value")) {
* return false;
* }
* }
*/
}
return true;
}
}
/**
* 优惠券对象
*/
class CouponEntity{
private int id;
private String name;
// 1比例扣减、2定额扣减
private int type;
// 门槛json {"shop":"1", "amount":100, "grade":2}
private String condition;
// 扣减的金额/比例
private double amount;
private Count countService;
public int getType() {
return type;
}
public CouponEntity(int id, String name, int type, String condition, double amount) {
this.id = id;
this.name = name;
this.type = type;
this.condition = condition;
this.amount = amount;
if (type == 1) {
this.countService = new Discount1();
} else {
this.countService = new Discount2();
}
}
public double getPrice(double price) {
return countService.count(price, amount);
}
}
interface Count{
double count(double price, double amount);
}
//比例扣减
class Discount1 implements Count{
@Override
public double count(double price, double amount) {
return price * amount / 100;
}
}
//定额扣减
class Discount2 implements Count{
@Override
public double count(double price, double amount) {
return price - amount;
}
}
class Good{
private String name;
private String shop;
private double price;
public double getPrice() {
return price;
}
public Good(String name, String shop, double price) {
this.name = name;
this.shop = shop;
this.price = price;
}
}
小结
涉及到不同类型进行不同的操作,可以采用策略模式。