当前位置: 首页
编程语言
基于Map和Bean的策略模式Java实现详解

基于Map和Bean的策略模式Java实现详解

热心网友 时间:2026-06-10
转载

策略模式堪称设计模式入门必修课,多数开发者初次学习时,往往通过构造方法或set方法选择具体策略。这种做法本身没有错误,但在实际业务中,若能结合Spring的依赖注入能力,完全可以采用更优雅、更简洁的实现方式。

直接给出结论:将策略实现交由Spring容器管理的Map + Bean方式,能够显著降低上下文类的维护复杂度。

1、关于策略模式

经典策略模式的定义与基础实现可参考菜鸟教程等常见资料,这类教程通常基于构造方法实现,清晰易懂。然而本文重点探讨的是在此之上再抽象一层,借助Spring的IoC容器来动态调度策略。

2、使用Map + Bean方式实现策略模式

核心改动点在于:不再通过set方法或构造方法显式指定具体策略实现,而是由Spring容器将所有策略实现注入到一个Map中,随后根据业务传来的标识(例如枚举值)直接匹配并调用。

下面以电商系统中常见的“商品价格计算”场景为例,完整演示具体实现步骤。

2.1 定义顶层计算价格接口

首先定义一个价格计算策略接口,该接口作为所有具体策略实现的顶层规范:

/**
 * 价格计算策略接口
 */
public interface PriceCalculatingStrategy {

    /**
     * 计算价格
     *
     * @param user   操作用户
     * @param factor 影响因素
     * @param prices 价格
     * @return 计算后的价格
     */
    BigDecimal calculatingProductPrices(User user, ProductPriceFactor factor, BigDecimal prices);
}

2.2 定义上下文

接下来是上下文类。核心要点是使用 @Resource 注入一个名为 priceStrategyMap 的Map,其中key为策略标识,value为对应的策略实现Bean。调用时,根据 factorType 从Map中取出目标策略并执行计算:

/**
 * 价格计算上下文
 */
@Component
public class PricesContext {

    @Resource(name = "priceStrategyMap")
    private Map calculatingStrategyMap;

    public BigDecimal calculating(User user, ProductPriceFactor factor, BigDecimal prices) {
        PriceCalculatingStrategy priceCalculatingStrategy = calculatingStrategyMap.get(factor.getFactorType());
        return priceCalculatingStrategy.calculatingProductPrices(user, factor, prices);
    }
}

2.3 策略注入类(组件)

策略注入环节通过 @Configuration 配置类实现策略注册中心。将VIP和邮费两种策略的Bean注入后,统一放入HashMap,并暴露为Spring管理的Bean:

@Configuration
public class PriceStrategyConfig {

    @Resource
    private VIPPriceStrategy vipPriceStrategy;

    @Resource
    private PostageStrategy postageStrategy;

    @Bean(name = "priceStrategyMap")
    public Map submitOrderStrategyMap() {
        Map strategyMap = new HashMap<>();
        strategyMap.put(FactorType.VIP.factorType, vipPriceStrategy);
        strategyMap.put(FactorType.POSTAGE.factorType, postageStrategy);
        return strategyMap;
    }

    @Getter
    enum FactorType {
        VIP(3),
        POSTAGE(2);

        FactorType(int factorType) {
            this.factorType = factorType;
        }

        private final int factorType;
    }
}

2.4 策略模式的具体实现

有了顶层接口与注册中心后,业务逻辑实现在具体策略类中。例如VIP折扣策略执行打折逻辑,而邮费策略则在商品原价基础上增加邮费金额:

@Service
public class VIPPriceStrategy implements PriceCalculatingStrategy{

    @Override
    public BigDecimal calculatingProductPrices(User user, ProductPriceFactor factor, BigDecimal prices) {
        // 这里忽略会员等级判断,用固定值测试
        return user.getId().equals(1L) ? prices.multiply(new BigDecimal("0.7")) : prices.multiply(factor.getValue());
    }
}

@Service(value = "postageStrategy")
public class PostageStrategy implements PriceCalculatingStrategy{

    @Override
    public BigDecimal calculatingProductPrices(User user, ProductPriceFactor factor, BigDecimal prices) {
        // 忽略发货地、收货地之间的邮费计算,测试用固定值
        return user.getId().equals(2L) ? prices.add(factor.getValue()) : prices;
    }
}

2.5 策略接口调用

在业务调用层,直接面向 PricesContext 上下文,通过 factorType 匹配对应策略实现,完成价格计算:

@Service
@RequiredArgsConstructor
public class ProductServiceImpl extends ServiceImpl implements ProductService {

    private final ProductPriceFactorService productPriceFactorService;
    private final PricesContext pricesContext;

    public BigDecimal calculatingProductPrices(Long productId, Integer productNum, User user) {
        // 忽略参数校验
        Product product = this.getById(productId);
        BigDecimal prices = product.getPrice().multiply(new BigDecimal(productNum));
        prices = calculatingFactor(user, productId, prices);
        return prices;
    }

    private BigDecimal calculatingFactor(User user, Long productId, BigDecimal prices) {
        List allFactorByProDuct = productPriceFactorService.getAllFactorByProDuct(productId);
        if (CollectionUtils.isNotEmpty(allFactorByProDuct)) {
            for (ProductPriceFactor factor : allFactorByProDuct) {
                prices = pricesContext.calculating(user, factor, prices);
            }
        }
        return prices;
    }
}

2.6 测试用例

基于Map+bean的策略模式实现方式

2.7 额外

最后说明,本示例基于SpringBoot + MySQL + Maven + MyBatisPlus搭建,代码编写相对随意,重点在于展示Map+Bean思路的优越性。如有不足之处,欢迎指正,共同进步。

总结

总体而言,这种实现方案具备以下几方面优势:

  • 策略注册与扩展只需在配置中心添加一个 put 操作,无需修改上下文类;
  • 业务侧仅需传入标识类型,实现完全解耦;
  • 借助Spring的IoC特性管理策略Bean生命周期,避免手动创建对象的繁琐。

希望该思路能为正在寻找更规范策略模式实现方案的开发者带来启发。

来源:https://www.jb51.net/program/3654180ee.htm

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
Python+Pytest接口自动化测试方案从零到一实战实现指南

Python+Pytest接口自动化测试方案从零到一实战实现指南

该方案基于Python+Pytest,采用分层结构清晰管理配置、接口、用例与数据。使用Requests库发送HTTP请求,通过YAML文件实现数据驱动与多环境灵活切换,利用Allure生成美观的可视化测试报告,支持统一断言机制,并可对接Jenkins实现持续集成自动化。

时间:2026-06-10 06:55
Python基础教程:列表查找排序与反转的常用方法

Python基础教程:列表查找排序与反转的常用方法

Python列表的查找(index与count用法)、排序(sort与sorted区别及key参数自定义排序)和反转(reverse、reversed及切片)操作详解,涵盖常见错误处理(如值不存在、类型错误)与实用技巧(安全查找、多级排序、频率统计),帮助高效处理列表数据。

时间:2026-06-10 06:55
使用Python扩展Unity编辑器实现自定义工具与工作流

使用Python扩展Unity编辑器实现自定义工具与工作流

为UnityPythonScripting包新增存根生成器、Python编辑器窗口和脚本浏览器。存根将C API转为Python类型信息,支持IDE代码补全。编辑器窗口避免C 编译等待。脚本窗口实现浏览与执行。

时间:2026-06-10 06:55
JVM崩溃FatalError问题排查与解决方案

JVM崩溃FatalError问题排查与解决方案

IntelliJIDEA运行Java服务时,启用定时调试器导致JVM因SIGSEGV崩溃,根本原因在于调试器的native代码与G1垃圾回收机制冲突。关闭“启用定时调试器”选项后,问题彻底解决。

时间:2026-06-10 06:54
基于Map和Bean的策略模式Java实现详解

基于Map和Bean的策略模式Java实现详解

利用Spring容器将策略实现注入到Map中,通过业务标识直接匹配调用,替代传统构造方法或set方法选择策略。该方法减少上下文类维护成本,策略扩展只需在配置中心增加映射,业务侧完全解耦,并利用IoC管理策略生命周期。

时间:2026-06-10 06:54
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜