☰
【架构-设计模式】----一篇文章搞定策略模式,轻松易懂
2026/9/30 13:29:09 网站建设 项目流程

一篇文章搞定策略模式,轻松易懂

一、什么是策略模式

策略模式(Strategy Pattern):定义一系列可互换的算法(策略),把每个算法封装成独立类,让算法和使用算法的代码解耦,算法可以动态替换。

核心一句话:同一个行为,有多种不同实现,可以随时切换,不用大量if/else。

适用场景:一堆if-else/switch,分支还会不断新增。

角色拆解(3个)

  1. 策略接口 Strategy:统一规范所有策略的方法
  2. 具体策略 ConcreteStrategy:实现接口,每种算法单独写一个类
  3. 上下文 Context:持有策略对象,对外提供调用入口,负责使用策略

二、举个生活化例子

场景:商场结算,不同会员折扣不一样

  • 普通会员:无折扣
  • 银卡会员:9折
  • 金卡会员:8折
    以后还可能新增钻石会员、限时折扣。

❌ 坏写法:大量if else

publicdoublecalcPrice(doubleoriginPrice,StringmemberType){if("普通".equals(memberType)){returnoriginPrice;}elseif("银卡".equals(memberType)){returnoriginPrice*0.9;}elseif("金卡".equals(memberType)){returnoriginPrice*0.8;}returnoriginPrice;}

缺点:新增折扣要改这个方法,违反开闭原则,if越来越臃肿。

✅ 策略模式改造

1. 策略接口

// 折扣策略接口publicinterfaceDiscountStrategy{// 计算折扣后价格doublegetPrice(doubleoriginPrice);}

2. 具体策略类

// 普通会员publicclassNormalStrategyimplementsDiscountStrategy{@OverridepublicdoublegetPrice(doubleoriginPrice){returnoriginPrice;}}// 银卡9折publicclassSilverStrategyimplementsDiscountStrategy{@OverridepublicdoublegetPrice(doubleoriginPrice){returnoriginPrice*0.9;}}// 金卡8折publicclassGoldStrategyimplementsDiscountStrategy{@OverridepublicdoublegetPrice(doubleoriginPrice){returnoriginPrice*0.8;}}

3. Context上下文(负责持有策略,对外提供服务)

publicclassPriceContext{// 持有策略privateDiscountStrategystrategy;// 构造传入策略publicPriceContext(DiscountStrategystrategy){this.strategy=strategy;}// 动态更换策略publicvoidsetStrategy(DiscountStrategystrategy){this.strategy=strategy;}// 执行计算publicdoublecalc(doubleoriginPrice){returnstrategy.getPrice(originPrice);}}

4. 客户端调用

publicclassTest{publicstaticvoidmain(String[]args){// 原价1000doubleprice=1000;// 金卡结算PriceContextcontext=newPriceContext(newGoldStrategy());System.out.println(context.calc(price));// 800.0// 动态切换成银卡context.setStrategy(newSilverStrategy());System.out.println(context.calc(price));//900.0}}

新增钻石会员:只需要新建DiamondStrategy实现接口,不用修改原有代码,满足开闭原则。

三、UML简图(文字版)

DiscountStrategy(接口) ↑ ┌────┬────┬────┐ Normal Silver Gold ↑ PriceContext 持有 DiscountStrategy

四、优缺点

✅ 优点

  1. 消除大量if/else、switch
  2. 算法独立,方便单元测试
  3. 策略可动态切换
  4. 新增策略不改动旧代码,符合开闭原则

❌ 缺点

  1. 策略增多,类数量膨胀,每一个策略都要新建类
  2. 客户端需要理解各个策略差异,才能选择合适策略

五、Java里的实际使用

  1. java.util.Comparator就是典型策略接口
    Collections.sort(list, Comparator),第二个参数就是不同排序策略,可以随时更换。
  2. 线程池拒绝策略RejectedExecutionHandler:Abort、Discard、CallerRuns 都是策略。

六、策略模式 VS 简单工厂(容易混淆)

  • 策略:侧重行为算法的动态替换,算法可运行时切换,上下文持有策略
  • 简单工厂:侧重对象创建,根据参数帮你new出对象,一般一次性获取

经常组合使用:工厂 + 策略,工厂根据类型生产对应的策略对象,客户端不用自己new策略。

七、Lambda简化(Java8优化,减少类爆炸)

策略是函数式接口,可以不用写一堆策略类,直接传lambda:

// 接口上加 @FunctionalInterface@FunctionalInterfacepublicinterfaceDiscountStrategy{doublegetPrice(doubleoriginPrice);}// 调用PriceContextctx=newPriceContext(p->p*0.7);System.out.println(ctx.calc(1000));

适合简单策略;复杂策略逻辑多,还是单独拆类。

八、什么时候选策略模式?

满足下面任意一条就可以考虑:

  1. 同一个业务,多种算法/方案,需要互相替换
  2. 代码充斥大量if else,后续分支还会持续增加
  3. 希望把算法独立出来,单独管理、单独测试

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询