最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
基于Map+bean策略模式实现方式
时间:2026-06-10 08:40:48 编辑:袖梨 来源:一聚教程网
1、关于策略模式
定义和基本实现可以参考菜鸟教程-策略模式 他这个是基于构造方法的
2、使用Map + Bean方式实现策略模式
原有策略顶层接口不变,但是修改上下文类的构造方式,不通过set方法和构造方法去获取指定的策略实现;
我这里以商城计算商品价格写的demo;
2.1 定义顶层计算价格接口
/**
* 价格计算策略接口
*/
public interface PriceCalculatingStrategy {
/**
* 计算价格
*
* @param user 操作用户
* @param factor 影响因素
* @param prices 价格
* @return 计算后的价格
*/
BigDecimal calculatingProductPrices(User user, ProductPriceFactor factor, BigDecimal prices);
}
2.2 定义上下文
/**
* 价格计算上下文
*/
@Component
public class PricesContext {
/**
* 通过Map + bean的方式把策略实现交给spring管理
*/
@Resource(name = "priceStrategyMap")
private Map<Integer, PriceCalculatingStrategy> calculatingStrategyMap;
/**
* 计算价格
*
* @param user 用户
* @param factor 价格影响因素
* @param prices 原价
* @return 原价减去或者加上各种因素产生的价格(如邮费、会员)
*/
public BigDecimal calculating(User user, ProductPriceFactor factor, BigDecimal prices) {
PriceCalculatingStrategy priceCalculatingStrategy = calculatingStrategyMap.get(factor.getFactorType());
return priceCalculatingStrategy.calculatingProductPrices(user,factor, prices);
}
}
2.3 策略注入类(组件)
/**
* 策略配置,注入到bean中
*/
@Configuration
public class PriceStrategyConfig {
/**
* vip对原价的影响
*/
@Resource
private VIPPriceStrategy vipPriceStrategy;
/**
* 邮费对原价的影响
*/
@Resource
private PostageStrategy postageStrategy;
/**
* 策略
*
* @return 策略模式的bean容器
*/
@Bean(name = "priceStrategyMap")
public Map<Integer, PriceCalculatingStrategy> submitOrderStrategyMap() {
Map<Integer, PriceCalculatingStrategy> strategyMap = new HashMap<>();
strategyMap.put(FactorType.VIP.factorType, vipPriceStrategy);
strategyMap.put(FactorType.POSTAGE.factorType, postageStrategy);
return strategyMap;
}
/**
* 价格影响因素类型枚举
* 这里应该单独成类,demo就直接内部了
*/
@Getter
enum FactorType {
/**
* vip
*/
VIP(3),
/**
* 邮费
*/
POSTAGE(2);
FactorType(int factorType) {
this.factorType = factorType;
}
private final int factorType;
}
}
2.4 策略模式的具体实现
/**
* vip 折扣
*/
@Service
public class VIPPriceStrategy implements PriceCalculatingStrategy{
/**
* 计算价格(这里假设是打折)
*
* @param factor 影响因素
* @param prices 价格
* @return 计算后的价格
*/
@Override
public BigDecimal calculatingProductPrices(User user, ProductPriceFactor factor, BigDecimal prices) {
// TODO 忽略会员等级实现的判断 测试用固定值
return user.getId().equals(1L) ? prices.multiply(new BigDecimal("0.7")) : prices.multiply(factor.getValue());
}
}
/**
* 发货地的邮费影响价格策略
*/
@Service(value = "postageStrategy")
public class PostageStrategy implements PriceCalculatingStrategy{
/**
* 计算价格 (这里假设是在基础邮费上增加值)
*
* @param factor 影响因素
* @param prices 价格
* @return 计算后的价格
*/
@Override
public BigDecimal calculatingProductPrices(User user, ProductPriceFactor factor, BigDecimal prices) {
// TODO 测试忽略发货地 收货地之间的邮费计算 测试用固定值
return user.getId().equals(2L) ? prices.add(factor.getValue()) : prices;
}
}
2.5 策略接口调用
这里直接调用上下文的计算方式,通过指定的类型(可以看2.3的bean注入)去获取策略实现。
/**
* 商品实现层
*/
@Service
@RequiredArgsConstructor
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {
private final ProductPriceFactorService productPriceFactorService;
private final PricesContext pricesContext;
/**
* 计算商品价格
*
* @param productId 货物id
* @param productNum 商品数量
* @param user 计算商品的用户
* @return {@link BigDecimal} 商品最后的价格
*/
public BigDecimal calculatingProductPrices(Long productId, Integer productNum, User user) {
//TODO 测试我这里忽略参数的校验
Product product = this.getById(productId);
BigDecimal prices = product.getPrice().multiply(new BigDecimal(productNum));
prices = calculatingFactor(user, productId, prices);
return prices;
}
/**
* 计算各种因素影响的价格
* @param user 计算商品的用户
* @param productId 产品id
* @param prices 价格
* @return 计算后的价格
*/
private BigDecimal calculatingFactor(User user, Long productId, BigDecimal prices) {
List<ProductPriceFactor> allFactorByProDuct = productPriceFactorService.getAllFactorByProDuct(productId);
if (CollectionUtils.isNotEmpty(allFactorByProDuct)) {
for (ProductPriceFactor factor : allFactorByProDuct) {
prices = pricesContext.calculating(user, factor, prices);
}
}
return prices;
}
}
2.6 测试用例

2.7 额外
本demo基于springboot + mysql + maven + mybatisplus实现,写的不是很好,一起成长
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持本站。
您可能感兴趣的文章:- 使用SpringBoot找不到Mapper的Bean问题及解决
- Java利用MapStruct优雅解决Bean映射难题的完全指南
- Java Bean与Map转换的几种方式
- 在Java中使用ModelMapper简化Shapefile属性转JavaBean实战过程
- 使用MapStruct进行Java Bean映射的方式
- 解决mapper自动装配识别不了,Could not autowire.No beans of‘UserMapper‘type found
- 解决mapper无法自动装配,未找到‘userMapper‘类型的Bean报错问题
相关文章
- CARSI高校联盟成员名单 - 2026年最新接入院校汇总 06-14
- 百科蝌蚪团是什么 - 百度百科官方科普团队 06-14
- XD - 专业设计与开发服务 06-14
- 医学检验技术专业详解 - 2026最新培养方向与就业前景 06-14
- 真香梗是什么意思 - 网络流行语起源与用法解析 06-14
- 王嘉尔最新动态与音乐作品 - 2026年全面回顾 06-14