首页 游戏 软件 资讯 排行榜 专题
首页
业界动态
别再死记设计模式了!Java 21+ 把 Strategy Pattern 玩出花,这才是现代写法

别再死记设计模式了!Java 21+ 把 Strategy Pattern 玩出花,这才是现代写法

热心网友
13
转载
2026-04-28

Strategy Pattern 从来没变,变的是 Ja va。从“类爆炸”到“函数式”,再到“类型驱动 + 模式匹配”,它已经从一种设计技巧,进化成了一种语言能力。

你写的不是设计模式,是“文件工厂”

还记得早期写策略模式的那种体验吗?

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

先定义一个接口,然后跟着N个实现类。需求但凡有点风吹草动,类文件的数量就跟着水涨船高。五种策略?那就意味着五个类文件。想加点校验逻辑?得,五个文件都得改一遍。

从纯粹的设计角度看,这确实叫“优雅解耦”;但切换到工程实践的视角,这感觉更像是——一个高效的“文件膨胀器”。

如果今天还在沿用这套写法,那你的代码风格,可能还停留在Ja va 7的时代。

别再只会“接口 + N个实现类”的老套路

不妨先回顾一下最经典、最传统的写法。

public interface PaymentStrategy {
    void pay(double amount);
}
public class CreditCardPayment implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("Paid " + amount + " using Credit Card");
    }
}
public class PayPalPayment implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("Paid " + amount + " using PayPal");
    }
}

调用端通常是这样的:

public class PaymentService {
    private PaymentStrategy strategy;
    public PaymentService(PaymentStrategy strategy) {
        this.strategy = strategy;
    }
    public void process(double amount) {
        strategy.pay(amount);
    }
}

平心而论,这套写法本身没有错,它完美体现了面向接口编程的思想。但问题也显而易见:

  • 类爆炸:策略数量与类文件数量线性增长。
  • 修改成本高:任何公共逻辑的调整都可能需要修改多个文件。
  • 逻辑分散:相同领域的逻辑散落在各个类中,难以形成整体视图。
  • 可读性下降:随着策略增多,在代码库中定位和理解具体逻辑变得越来越困难。

别再只会用 Ja va 8 Lambda 的“半升级版本”

Ja va 8引入Lambda表达式后,很多人觉得已经迈向了“现代化”:

PaymentStrategy creditCard = amount ->
        System.out.println("Paid " + amount + " using Credit Card");
PaymentStrategy paypal = amount ->
        System.out.println("Paid " + amount + " using PayPal");

看起来确实清爽了不少,至少文件数量降下来了。但深究下去,核心问题依然存在:

  • 没有类型约束:策略本质上还是一个函数对象,缺乏丰富的类型信息。
  • 复杂逻辑难维护:当策略逻辑变得复杂时,内联的Lambda会变得臃肿且难以测试。
  • 扩展性依旧有限:增加新的策略类型,仍然需要手动修改调用处的逻辑。

可以说,这只是利用新语法做了“文件减肥”,并没有触及策略模式“模型”的升级。

别再忽略 Ja va 17 的 sealed + record 带来的结构升级

真正的转折点,其实是从Ja va 17开始的。sealed classes/interfaces和record这两个特性,为我们重新构思策略模式提供了全新的建筑材料。

我们可以用sealed interface来严格限定策略的家族成员,用record来清晰表达策略所携带的数据结构。

// 定义策略的密封接口,明确声明允许的实现
package com.icoderoad.strategy;
public sealed interface PaymentStrategy
        permits CreditCard, PayPal {}

// 策略一:信用卡支付,用record封装卡号数据
package com.icoderoad.strategy;
public record CreditCard(String cardNumber) implements PaymentStrategy {}

// 策略二:PayPal支付,用record封装邮箱数据
package com.icoderoad.strategy;
public record PayPal(String email) implements PaymentStrategy {}

这样一来,策略不再仅仅是封装一个“行为”的抽象,而是进化为“数据 + 类型”的强组合。每种策略是什么,能携带什么数据,在编译期就一清二楚。

别再写 if-else,Ja va 21 的 pattern matching 才是核心玩法

到了Ja va 21,随着模式匹配for switch的成熟,策略模式终于完成了它的终极进化。处理逻辑可以变得如此集中和直观:

package com.icoderoad.strategy;
public class PaymentProcessor {
    public static void process(PaymentStrategy strategy, double amount) {
        switch (strategy) {
            case CreditCard cc ->
                 System.out.println("Paid " + amount + " with card: " + cc.cardNumber());
            case PayPal pp ->
                 System.out.println("Paid " + amount + " via PayPal: " + pp.email());
        }
    }
}

这种写法带来的变化是本质性的:

  • 不再需要N个类分散逻辑:所有策略的分支处理集中在一处,一目了然。
  • 所有策略集中在一个可控范围:阅读和维护者无需在多个文件间跳转。
  • 编译期保证类型安全:switch表达式会检查是否覆盖了所有sealed接口的许可类型。
  • 代码结构更加线性、可读:逻辑流是线性的,极大地降低了认知负担。

别再把策略模式当“类设计”,它本质是“分支控制”

这里存在一个普遍的误解。策略模式的核心目的,从来不是为了展示多态技巧,它的本质是:

在运行时选择不同逻辑路径

现代Ja va语法给了我们更直接、更声明式的方式来表达这一意图:

public static void process(PaymentStrategy strategy, double amount) {
    switch (strategy) {
        case CreditCard cc -> handleCard(cc, amount);
        case PayPal pp -> handlePayPal(pp, amount);
    }
}

对比旧时代的写法,优势立现:

  • 少了类跳转:无需在多个实现类中寻找逻辑。
  • 少了思维负担:逻辑脉络集中,上下文清晰。
  • 多了编译期校验:编译器帮你确保处理了所有已知策略,避免遗漏。

用一张流程图看清新旧策略模式差异

图片

别再担心扩展性,现代写法反而更安全

肯定有人会质疑:把所有逻辑写在一个switch里,是不是违反了开闭原则?新增策略不是还得修改这个switch吗?

其实,情况正好相反。这种现代写法在大型或严谨的系统中,反而提供了更强的安全性。

传统模式的问题:

  • 新增策略:需要新增类,并且必须在代码的某个地方(可能是工厂或配置)修改调用逻辑来纳入这个新类。
  • 逻辑分散风险:相关逻辑分散在各处,容易在修改时产生不一致。

现代模式的优势:

  • sealed 限制策略范围:策略类型是封闭的、已知的,防止不可控的扩展。
  • switch 强制覆盖所有分支:如果新增一个策略类型(如Alipay)但没有在switch中处理,编译器会直接报错,这杜绝了运行时遗漏。
  • 修改集中,可控性更高:所有策略的逻辑入口明确且唯一,便于审计和管控。

什么时候该用“现代策略模式”?

这种基于密封类型和模式匹配的现代策略模式,并非银弹,它有自己最适合的战场:

适用场景:

  • 策略数量相对有限且稳定,例如支付方式、订单状态机、通知渠道等。
  • 策略逻辑需要集中管理和审视,强调可读性与可维护性。
  • 对类型的严谨性有高要求,希望借助编译器来保证逻辑完整性。

不适用场景:

  • 策略需要高度动态加载,如插件化系统。
  • 策略完全由第三方提供,其类型不可在编译期预知。

设计模式不会过时,但写法一定会

说到底,策略模式的思想内核从未改变,变化的是Ja va这门语言本身。它从最初导致“类爆炸”的经典实现,演进到利用Lambda的“函数式”简化,再到如今“类型驱动 + 模式匹配”的声明式表达。策略模式,已经从一种需要刻意套用的“设计技巧”,进化成了语言原生支持的“表达能力”。

真正的高手,或许不在于能背诵多少种设计模式,而在于懂得审时度势——知道在语言进化的新阶段,何时该放下过去的经典实现,用更现代、更贴合语言特性的方式,将同样的思想重写一遍。

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

最新APP

宝宝过生日
宝宝过生日
应用辅助 04-07
台球世界
台球世界
体育竞技 04-07
解绳子
解绳子
休闲益智 04-07
骑兵冲突
骑兵冲突
棋牌策略 04-07
三国真龙传
三国真龙传
角色扮演 04-07

热门推荐

Signlz AI : AI辅助PRD生成工具
AI
Signlz AI : AI辅助PRD生成工具

需求人群 如果你是一位产品经理或相关专业人士,正在为如何高效启动一个新项目、打磨一份专业的产品需求文档(PRD)而头疼,那么Signlz可能就是为你量身打造的工具。它核心解决的,就是帮助这个群体快速且高质量地迈出产品创新的第一步。 使用场景 那么,具体在哪些环节它能大显身手呢?最典型的,莫过于当你需

热心网友
04.28
GraphQL AI : AI开发者平台
AI
GraphQL AI : AI开发者平台

需求人群 如果你正在开发AI工具、机器人或者聊天助手,那么下面这个平台值得你特别关注。它瞄准的正是这个快速发展的开发者社区。 使用场景 具体能拿它来做什么呢?场景其实很丰富。比如,你可以用它快速搭建一个聊天机器人,来高效处理用户的那些常见问题,解放人力。艺术创作方面,它集成的图像生成模型能帮你产出风

热心网友
04.28
当Perps DEX进入下一阶段,交易者真正需要什么?
web3.0
当Perps DEX进入下一阶段,交易者真正需要什么?

2026 年 4 月,加密市场重新升温。BTC 一度触及 7 9 万美元,随后在 7 7 万美元附近震荡。随着资金回流、宏观预期变化和机构交易活跃,市场注意力再次回到 BTC 及其衍生品交易。 行情一旦回归,最先热闹起来的总是合约市场。更高的杠杆、更低的费用、更快的开仓速度,总能迅速把交易者拉回屏幕

热心网友
04.28
Vidby:字幕翻译配音服务,一款专业的AI视频翻译和配音工具
AI
Vidby:字幕翻译配音服务,一款专业的AI视频翻译和配音工具

想把你的视频内容传递给全世界的观众?语言障碍往往是最大的拦路虎。好在,现在有了专业的解决方案。Vidby,这款由瑞士Vidby AG公司打造的AI视频翻译与配音工具,正是为此而生。它能快速且精准地处理视频翻译、字幕生成和语音配音等一系列任务,帮你轻松跨越语言鸿沟。 那么,它是如何做到的呢?核心在于其

热心网友
04.28
百度:文心下一代模型 4.5 系列 6 月 30 日起开源
AI
百度:文心下一代模型 4.5 系列 6 月 30 日起开源

百度官宣文心大模型4 5系列将至,并定下开源时间表 情人节这天,国内AI领域迎来一则重磅消息。百度正式宣布,将在未来几个月内,逐步推出其文心大模型的下一代版本——4 5系列。而真正的重头戏在于,该系列模型将从今年6月30日起正式开源。这意味着,开发者与企业获得行业顶级大模型技术的门槛,将迎来一次显著

热心网友
04.28