设计模式中怎么使用策略模式实现多种折扣计算引擎

风芳吖_4931

风芳吖_4931

2026-08-10

330人浏览

原创

策略模式最适合解决同一问题有多种算法实现且需动态切换的场景,如折扣计算;其核心角色包括定义统一方法的策略接口、专注单一逻辑的具体策略类、以及持有策略引用并负责调用的上下文。

设计模式中怎么使用策略模式实现多种折扣计算引擎

策略模式最适合解决“同一问题有多种算法实现,且需要动态切换”的场景。折扣计算正是典型代表:不同用户类型、活动规则、商品类别对应不同折扣逻辑,硬编码在 if-else 里会导致每次新增策略都要改主逻辑,违反开闭原则。

明确三个核心角色

先理清职责分工,避免混淆:

  • 折扣策略接口(Strategy):定义统一方法,比如 apply(double originalPrice),所有具体折扣算法必须实现它
  • 具体折扣类(Concrete Strategy):每个类只专注一种折扣逻辑,例如 FixedAmountDiscount(减5元)、PercentageDiscount(打8折)、ThresholdDiscount(满300减50)
  • 折扣上下文(Context):持有当前策略引用,提供 setStrategy() 和 calculate() 方法,不关心具体怎么算,只负责调用

用 Spring 实现自动装配与动态选择

真实项目中不会手动 new 策略对象,而是靠 Spring 容器管理:

Java Api Extractor
Java Api Extractor

从 Java 项目中提取 Controller 层接口定义为 JSON 数据。

下载
  • 给每个具体策略类加上 @Component 注解,并按约定命名 Bean(如 fixedDiscount、percentageDiscount)
  • 在上下文类中注入 Map,Key 可以是枚举值或策略编码(如 "FIXED"、"PERCENT")
  • 根据业务参数(如优惠券类型、用户等级)查出对应策略 Bean,直接调用

支持运行时策略组合与降级

单一折扣不够用?电商常需叠加(如“满减+会员折”),这时可扩展 Context:

  • 让 Context 接收多个策略,按顺序执行(如先满减再打折),结果链式传递
  • 增加兜底机制:当某策略因参数异常无法执行时,自动 fallback 到默认策略(如无折扣)
  • 策略本身也可带校验逻辑,比如 ThresholdDiscount.apply() 先判断是否达门槛,不满足则返回原价

避免常见陷阱

写得像策略模式,但没真正解耦,容易踩坑:

  • 不要在策略类里写数据库查询或远程调用——策略应是纯计算,外部数据由 Context 或 Service 提前准备好传入
  • 别把策略对象当成单例全局共享——如果策略内部有状态(如缓存计数),要用 prototype 作用域或每次新建
  • 策略命名要反映业务语义,而不是技术实现,比如用 VipEightFiveDiscount 而不是 MultipliedBy085Strategy

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

java

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

2026.10.28

60

16

Vite 如何搭配 Vue.js
Vite 如何搭配 Vue.js

Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。

2026.10.28

40

15

Vite 项目目录怎么看
Vite 项目目录怎么看

Vite项目目录专题汇集入口文件、src源码、public静态资源、路径别名、项目根目录和构建输出目录相关的已审核文章,帮助读者理解各文件夹的用途与引用方式。

2026.10.28

120

10

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

2026.10.22

140

11

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

2026.10.22

120

10

Golangci-lint检查器使用教程
Golangci-lint检查器使用教程

本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。

2026.10.22

80

15

Gradle怎么构建Java项目
Gradle怎么构建Java项目

本专题介绍Gradle Java项目构建方法,涵盖Java插件配置、依赖声明、源码编译、测试执行和打包检查,帮助你理解各阶段的任务关系,逐步完成项目构建。

2026.10.22

40

10

PHP时间戳漏洞修复教程
PHP时间戳漏洞修复教程

本专题汇总PHP常见时间戳漏洞,包括2038年溢出、时区漂移、时间戳伪造、重放攻击、时间盲注与日志审计失效等,并给出升级64位环境、使用 DateTimeImmutable、统一UTC、严格超时校验、预处理绑定、hash_equals 比对等修复方案,帮助开发者快速排查和加固时间相关代码。

2026.10.22

80

25

Golangci-lint配置文件与规则设置
Golangci-lint配置文件与规则设置

本专题聚焦Golangci-lint YAML配置文件,讲清运行参数、规则启停、目录排除、问题过滤及严重级别设置,便于团队统一检查标准。

2026.10.22

40

15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习