Java策略模式从入门到实战:小白也能看懂的设计模式指南

Java策略模式从入门到实战:小白也能看懂的设计模式指南

🌟 一句话理解策略模式:把"怎么做"抽出来,让程序能灵活换算法,而不改主逻辑。


① 技术栈用途介绍:它到底能解决什么问题?

想象你开了一家「智能收银小铺」,顾客付款时可选:微信支付、支付宝、现金、会员积分......每种方式的校验规则、扣款流程、成功回调都不一样 。如果用 if-else 硬编码写死在结算方法里:

java 复制代码
if (payType.equals("wechat")) { /* 微信逻辑 */ }
else if (payType.equals("alipay")) { /* 支付宝逻辑 */ }
// ......10种支付方式?加一个就改一次主方法!

问题来了

  • 代码臃肿、难以维护;
  • 新增支付方式要动核心业务(违反"开闭原则");
  • 单元测试困难,逻辑耦合严重。

策略模式登场

就像给收银台装上「可插拔的支付卡槽」------微信卡、支付宝卡、现金卡......各自封装好自己的动作,收银员(主业务)只管"插哪张卡、按确认键",不用关心卡内部怎么工作。

📌 典型场景

  • 多种算法切换(排序、压缩、加密);
  • 多渠道通知(短信/邮件/钉钉);
  • 不同风控策略(新用户宽松、老用户严格);
  • 电商促销计算(满减、折扣、赠品)。

② 环境准备与安装配置:5分钟搭好实验环境

无需额外安装!策略模式是纯Java语言级设计思想,JDK 8+ 即可运行(推荐 JDK 17)。你只需要:

开发工具 :IntelliJ IDEA(社区版免费)或 VS Code + Java Extension Pack ✅ 项目构建:Maven(IDE通常自带)

🔧 创建 Maven 工程(命令行速建)

bash 复制代码
mvn archetype:generate -DgroupId=com.example.strategy \
                      -DartifactId=strategy-demo \
                      -DarchetypeArtifactId=maven-archetype-quickstart \
                      -DinteractiveMode=false

💡 避坑提醒

  • ❌ 不要试图找"策略模式依赖库"------它不是框架,不需要 pom.xml 加依赖!
  • ✅ 关键是理解接口 + 多实现类 + 上下文委托 的三件套结构;
  • ⚠️ 若报错 Cannot resolve symbol 'xxx',检查是否漏写 public interface / implements / 包声明。

③ 入门实践:30秒跑通第一个策略Demo

我们以「订单优惠计算」为例,实现:

  • 普通订单 → 无优惠
  • VIP订单 → 9折
  • 黑金订单 → 满200减50

Step 1:定义策略接口

java 复制代码
// src/main/java/com/example/strategy/PromotionStrategy.java
public interface PromotionStrategy {
    double calculateDiscount(double originalPrice);
}

Step 2:编写具体策略实现类

java 复制代码
// 普通策略
public class NoDiscountStrategy implements PromotionStrategy {
    @Override
    public double calculateDiscount(double originalPrice) {
        return 0.0;
    }
}

// VIP策略(9折 → 减10%)
public class VipDiscountStrategy implements PromotionStrategy {
    @Override
    public double calculateDiscount(double originalPrice) {
        return originalPrice * 0.1;
    }
}

// 黑金策略(满200减50)
public class BlackGoldStrategy implements PromotionStrategy {
    @Override
    public double calculateDiscount(double originalPrice) {
        return originalPrice >= 200 ? 50.0 : 0.0;
    }
}

Step 3:创建上下文(收银员)

java 复制代码
// src/main/java/com/example/strategy/OrderContext.java
public class OrderContext {
    private PromotionStrategy strategy;

    public void setStrategy(PromotionStrategy strategy) {
        this.strategy = strategy;
    }

    public double applyDiscount(double price) {
        return price - strategy.calculateDiscount(price);
    }
}

Step 4:编写测试入口(运行它!)

java 复制代码
// src/test/java/com/example/strategy/StrategyDemoTest.java
public class StrategyDemoTest {
    public static void main(String[] args) {
        OrderContext context = new OrderContext();

        // 场景1:普通用户下单 ¥100
        context.setStrategy(new NoDiscountStrategy());
        System.out.println("普通用户实付:" + context.applyDiscount(100)); // 100.0

        // 场景2:VIP用户下单 ¥100
        context.setStrategy(new VipDiscountStrategy());
        System.out.println("VIP用户实付:" + context.applyDiscount(100)); // 90.0

        // 场景3:黑金用户下单 ¥250
        context.setStrategy(new BlackGoldStrategy());
        System.out.println("黑金用户实付:" + context.applyDiscount(250)); // 200.0
    }
}

✅ 运行输出:

复制代码
普通用户实付:100.0
VIP用户实付:90.0
黑金用户实付:200.0

🎉 成功!你已亲手实现了策略模式 ------ 零框架、纯Java、一目了然


④ 进阶与原理:不止于"能用",更要懂"为什么这么设计"

🔍 核心机制图解

复制代码
[客户端] → 设置策略 → [OrderContext(上下文)]
                          ↓ 委托调用
       [PromotionStrategy(接口)] ← 实现关系 ← [NoDiscount/Vip/BlackGold...]
  • 上下文不依赖具体实现:只持有接口,随时可切换;
  • 新增策略零侵入 :加个 StudentDiscountStrategy 类,不改任何已有代码;
  • 天然支持依赖注入 :Spring 中可直接 @Autowired 注入不同策略 Bean。

🚀 高级技巧(实战加分项)

✅ 策略工厂 + 枚举驱动(告别硬编码 new)
java 复制代码
public enum PayType {
    WECHAT(new WechatStrategy()),
    ALIPAY(new AlipayStrategy()),
    CASH(new CashStrategy());

    private final PromotionStrategy strategy;
    PayType(PromotionStrategy strategy) { this.strategy = strategy; }
    public PromotionStrategy getStrategy() { return strategy; }
}

// 使用:context.setStrategy(PayType.WECHAT.getStrategy());
✅ Spring整合(自动注册 & 条件化策略)
java 复制代码
@Component("vipStrategy")
@ConditionalOnProperty(name = "user.level", havingValue = "vip")
public class VipDiscountStrategy implements PromotionStrategy { ... }
⚖️ 性能注意点
  • 策略对象建议单例复用(避免频繁 new);
  • 高并发下可用 ConcurrentHashMap<String, Strategy> 缓存策略实例。

⑤ 总结与评估:什么时候该用?什么时候绕道?

| 维度 | 说明 | |--------------|----------------------------------------------------------------------| | ✅ 优点 | • 开闭原则完美践行(对扩展开放,对修改关闭)

• 解耦清晰,测试友好

• 易于组合、替换、单元化 | | ❌ 局限性 | • 策略过多时类爆炸(如100种支付 → 100个类)→ 可结合工厂/规则引擎优化

• 无法处理策略间强依赖或状态流转 | | 🎯 适用场景 | • 同一行为有多种实现方式

• 业务规则经常变动

• 需要运行时动态选择算法 | | 🆚 vs 状态模式 | 策略关注「算法替换」,状态关注「对象自身状态改变导致行为变化」(如订单:待支付→已发货→已完成) | | 📚 延伸学习 | • 结合 Spring @Qualifier 实现策略注入

• 进阶:Drools 规则引擎(超复杂策略场景)

• 对比学习:模板方法模式(父类定骨架,子类填细节) |

💡 给小白的学习建议

  1. 先照着本文 Demo 敲3遍,确保完全理解三要素(接口、实现类、上下文);
  2. 尝试把「登录验证方式」(账号密码 / 手机验证码 / 第三方OAuth)改成策略模式;
  3. 阅读 JDK 源码中的 Comparator 接口------它就是策略模式的经典应用!

结语:设计模式不是炫技,而是为代码"延长保质期"。当你不再为加一个新功能而恐惧修改旧代码时,你就真正入门了工程思维。策略模式,是你走向优雅编程的第一步轻装启程。

💬 文末互动:你在项目中用过策略模式吗?遇到过哪些坑?欢迎评论区交流~

相关推荐
xuxie992 小时前
Next 13 sqlite3 查找、网页
java·数据库·oracle
꯭ 瞎꯭扯꯭蛋꯭2 小时前
3万字80道Java基础经典面试题总结
java·开发语言
程序员Terry2 小时前
别再用 if-else 堆砌代码了!策略模式让你的代码优雅十倍
java·设计模式
what丶k2 小时前
深入浅出责任链模式:解耦流程的优雅设计之道
java·责任链模式
未来之窗软件服务2 小时前
服务器运维(四十七)鸿蒙系统Mongoose服务器伪请求pseudo http —东方仙盟
java·运维·服务器·服务器运维·仙盟创梦ide·东方仙盟
SimonKing2 小时前
被AI编程折磨的苦不堪言:一边喊真香,一边想砸键盘
java·后端·程序员
I_LPL2 小时前
hot 100 普通数组、矩阵专题
java·数据结构·矩阵·动态规划·贪心·数组·求职面试
顺风尿一寸2 小时前
深入剖析 Linux 内核 TCP Poll 机制:等待、唤醒与同步
java·linux
新时代Java农民工2 小时前
刚安装好的IDEA在插件库里面搜索不到要安装的插件
java·ide