0

0

如何实现Java的策略模式_多态在业务逻辑切换中的应用

P粉602998670

P粉602998670

发布时间:2026-02-28 08:27:12

|

412人浏览过

|

来源于php中文网

原创

策略接口必须用 interface 而非 abstract class,因其需支持任意类(含已有父类者)实现,确保运行时动态替换与解耦;abstract class 强制继承,破坏即插即用性。

如何实现java的策略模式_多态在业务逻辑切换中的应用

策略接口定义时,为什么必须用 interface 而不是 abstract class

因为策略模式的核心是「运行时动态替换」,需要让不同业务逻辑实现完全解耦、互不继承。用 interface 能保证任意类(哪怕是已有父类的)都能实现它;而 abstract class 会强制继承,破坏策略的即插即用性。

常见错误:把策略基类写成 abstract class StrategyBase,结果发现订单服务类已经继承了 Service,无法再继承它——只能退回去重写成接口。

  • 所有策略实现类应只依赖 Strategy 接口,不感知彼此
  • 接口方法不要带默认实现(Java 8+ 的 default 方法容易诱使你塞共享逻辑,违背策略隔离原则)
  • 如果真有公共行为,抽成工具类或通过构造参数注入,别放进策略接口里

Spring 中如何自动装配一堆策略实现

@Autowired 注入 List<strategy></strategy>Map<string strategy></string>,Spring 会自动把所有实现该接口的 Bean 收集进来。这是最轻量、最符合 Spring 原生机制的做法。

常见错误:手动 new 实例、或用 if-else 判断类型再 cast,既难测又绕过 Spring 生命周期管理。

立即学习Java免费学习笔记(深入)”;

Q.AI视频生成工具
Q.AI视频生成工具

支持一分钟生成专业级短视频,多种生成方式,AI视频脚本,在线云编辑,画面自由替换,热门配音媲美真人音色,更多强大功能尽在QAI

下载
  • 确保每个策略实现类都加了 @Component(或子注解如 @Service
  • 想按名称区分策略?在实现类上加 @Qualifier("payAlipay"),然后用 Map<string strategy></string> 注入,key 就是 qualifier 值
  • 别在策略类里直接 @Autowired 其他 service——它只是个纯逻辑容器,依赖应由调用方传入或通过构造器注入

运行时选策略,if-else 和 Map 查找哪个更安全

Map<string strategy></string> 查找。if-else 容易漏分支、难覆盖、改起来像踩雷;Map 查找失败会抛 NullPointerException 或明确提示 key 不存在,问题暴露得早。

典型场景:支付渠道由前端传 "alipay""wechat" 字符串决定走哪个策略。

  • 初始化 Map 时用 new HashMap(strategies),别用 ImmutableMap——后续新增策略要重启应用,失去动态性
  • 查找前先校验 key 是否存在:if (!strategyMap.containsKey(channel)) { throw new IllegalArgumentException("Unsupported channel: " + channel); }
  • 避免用枚举做 key:枚举值硬编码在代码里,前端传错字符串就进不了 switch,但 Map 至少能兜住异常

策略类里调用外部服务,怎么避免 NPE 和超时雪崩

策略本身不该管重试、降级、熔断——那是调用方(比如订单服务)的责任。策略只负责「给定输入,返回确定输出」,否则职责混乱,单元测试没法写。

常见错误:在 doExecute() 里直接调 paymentClient.pay(),没包 try-catch,一出错整个下单流程卡死。

  • 策略方法签名保持简单:Result execute(Request request),不抛受检异常
  • 外部调用统一由上层封装(比如 PaymentService),策略只接收一个已封装好的 PaymentExecutor 实例作为参数
  • 超时时间必须由调用方控制,策略内部不做 Thread.sleep 或自定义 timeout
策略最难的不是写接口和实现,是守住边界:它只做分支逻辑,不碰基础设施,不掺杂状态,不决定失败后怎么办。一旦开始在里面加日志埋点、缓存判断、异步回调,就不再是策略,而是裹着策略外壳的业务胶水。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

146

2025.08.06

Java Spring Security 与认证授权
Java Spring Security 与认证授权

本专题系统讲解 Java Spring Security 框架在认证与授权中的应用,涵盖用户身份验证、权限控制、JWT与OAuth2实现、跨站请求伪造(CSRF)防护、会话管理与安全漏洞防范。通过实际项目案例,帮助学习者掌握如何 使用 Spring Security 实现高安全性认证与授权机制,提升 Web 应用的安全性与用户数据保护。

84

2026.01.26

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

870

2023.08.02

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

835

2023.08.22

switch语句用法
switch语句用法

switch语句用法:1、Switch语句只能用于整数类型,枚举类型和String类型,不能用于浮点数类型和布尔类型;2、每个case语句后面必须跟着一个break语句,以防止执行其他case的代码块,没有break语句,将会继续执行下一个case的代码块;3、可以在一个case语句中匹配多个值,使用逗号分隔;4、Switch语句中的default代码块是可选的等等。

563

2023.09.21

Java switch的用法
Java switch的用法

Java中的switch语句用于根据不同的条件执行不同的代码块。想了解更多switch的相关内容,可以阅读本专题下面的文章。

436

2024.03.13

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

Golang 并发编程模型与工程实践:从语言特性到系统性能
Golang 并发编程模型与工程实践:从语言特性到系统性能

本专题系统讲解 Golang 并发编程模型,从语言级特性出发,深入理解 goroutine、channel 与调度机制。结合工程实践,分析并发设计模式、性能瓶颈与资源控制策略,帮助将并发能力有效转化为稳定、可扩展的系统性能优势。

2

2026.02.27

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3.9万人学习

C# 教程
C# 教程

共94课时 | 10.3万人学习

Java 教程
Java 教程

共578课时 | 73.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号