代码基于SpringBoot
需求假设:
平台有不同的会员等级,不同的会员等级消费折扣不一样
1.普通用户没折扣
2.vip1拥有9折优惠(可以复杂化加优惠券,这里举例就简单化了)
3.vip2拥有8折优惠(可以复杂化加优惠券,这里举例就简单化了)
4.vip3拥有7折优惠(可以复杂化加优惠券,这里举例就简单化了)
当然,用if-else语句是可以实现如上需求的,但是无论是可读性或者是可维护性都不高,可以用策略模式去改善,代码如下:
1.定义用户等级类型
// 共有四种用户类型的枚举,对应不同的折扣优惠方式
@Getter
public enum UserType {
USER,
VIP1,
VIP2,
VIP3
}
2.定义统一计算折扣接口,让不同的用户类型去具体实现
public interface UserPayService {
/**
* 用户类型解析
*
* @return 用户类型
*/
UserType geinUserType();
/**
* 计算订单价格
*
* @param orderPrice 原价
* @return 折后价
*/
BigDecimal calcPrice(BigDecimal orderPrice);
}
3.不同的用户实现统一计算接口
// 普通用户的计算价格方式实现
// 这个注解是要的,让spring实例化
@Component
public class UserPayServiceImpl implements UserPayService {
@Override
public UserType geinUserType() {
return UserType.USER;
}
@Override
public BigDecimal calcPrice(BigDecimal orderPrice) {
// 普通用户 没折扣
return orderPrice;
}
}
// Vip1用户的计算价格方式实现
// 这个注解是要的,让spring实例化
@Component
public class Vip1PayServiceImpl implements UserPayService {
@Override
public UserType geinUserType() {
return UserType.VIP1;
}
@Override
public BigDecimal calcPrice(BigDecimal orderPrice) {
// vip1 9折(或者叠加优惠券)
BigDecimal discount = new BigDecimal("0.9");
return orderPrice.multiply(discount);
}
}
// Vip2用户的计算价格方式实现
// 这个注解是要的,让spring实例化
@Component
public class Vip2PayServiceImpl implements UserPayService {
@Override
public UserType geinUserType() {
return UserType.VIP2;
}
@Override
public BigDecimal calcPrice(BigDecimal orderPrice) {
// vip1 8折 (或者叠加优惠券)
BigDecimal discount = new BigDecimal("0.8");
return orderPrice.multiply(discount);
}
}
// Vip3用户的计算价格方式实现
// 这个注解是要的,让spring实例化
@Component
public class Vip3PayServiceImpl implements UserPayService {
@Override
public UserType geinUserType() {
return UserType.VIP3;
}
@Override
public BigDecimal calcPrice(BigDecimal orderPrice) {
// vip1 7折(或者叠加优惠券)
BigDecimal discount = new BigDecimal("0.7");
return orderPrice.multiply(discount);
}
}
4.实现spring的ApplicationContextAware接口进行bean自定义管理的策略类
// 这个注解是要的,让spring实例化
@Component
public class PayStrategyService implements ApplicationContextAware {
private Map<UserType, UserPayService> userPayServiceMap = new ConcurrentHashMap<>();
public BigDecimal calcPrice(UserType userEnum, BigDecimal orderPrice) {
UserPayService userPayService = this.userPayServiceMap.get(userEnum);
if (userPayService != null) {
return userPayService.calcPrice(orderPrice);
}
return orderPrice;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, UserPayService> userPayServiceBeans = applicationContext.getBeansOfType(UserPayService.class);
// 把不同的用户类型UserType和其实现类一一对应放入Map
userPayServiceBeans.values().forEach(userPayService -> userPayServiceMap.put(userPayService.geinUserType(), userPayService));
}
}
5.使用方式,此处使用springboot test测试
@SpringBootTest
public class TestApplication {
// 策略类注入
@Autowired
private PayStrategyService payStrategyService;
@Test
public void Test() {
BigDecimal orderPrice = new BigDecimal(1000);
System.out.println("普通用户最终价格:" + payStrategyService.calcPrice(UserType.USER, orderPrice));
System.out.println("Vip1用户最终价格:" + payStrategyService.calcPrice(UserType.VIP1, orderPrice));
System.out.println("Vip2用户最终价格:" + payStrategyService.calcPrice(UserType.VIP2, orderPrice));
System.out.println("Vip3用户最终价格:" + payStrategyService.calcPrice(UserType.VIP3, orderPrice));
}
}