策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来并使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端,从而实现灵活的算法切换。
简单来说,策略模式就像 “出行方式选择”—— 去同一个目的地可以选择步行、骑车、开车等不同策略,这些策略(算法)可根据情况随时切换,而不影响出行的目标。
策略模式的UML类图如下:

上图中:
- 策略接口(Strategy):定义所有具体策略必须实现的方法(如
execute()),统一算法的调用方式。
- 具体策略(ConcreteStrategyA/B/C):实现策略接口,包含具体的算法逻辑(如不同的排序算法、支付方式)。
- 环境类(Context):持有一个策略对象的引用,提供
setStrategy()方法动态切换策略,通过doOperation()方法调用当前策略的算法。
策略模式的核心价值是算法的封装与切换,它将算法的定义与使用分离,使得:
- 可以在不修改客户端的情况下新增算法(符合开闭原则)
- 可以在运行时动态切换算法
- 避免使用多重条件判断(if-else/switch)
常见应用场景:支付方式选择(微信、支付宝、银行卡)、排序算法切换、折扣计算策略等。
下面以 “电商平台的折扣计算” 为例,展示策略模式的实现。不同用户(普通用户、会员、VIP)有不同的折扣策略,且折扣规则可能随时调整,使用策略模式可以灵活切换和扩展这些折扣算法。
首先,定义一个统一的折扣策略抽象接口
1 2 3 4 5
| interface DiscountStrategy { double calculate(double originalPrice); }
|
然后定义针对不同用户的折扣策略
1 2 3 4 5 6 7 8
| class NormalUserDiscount implements DiscountStrategy { @Override public double calculate(double originalPrice) { System.out.println("普通用户:无折扣"); return originalPrice; } }
|
1 2 3 4 5 6 7 8 9
| class MemberDiscount implements DiscountStrategy { @Override public double calculate(double originalPrice) { double discountedPrice = originalPrice * 0.9; System.out.println("会员用户:9折,折后价:" + discountedPrice); return discountedPrice; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| class VipDiscount implements DiscountStrategy { @Override public double calculate(double originalPrice) { double tempPrice = originalPrice * 0.8; if (tempPrice >= 100) { tempPrice -= 20; } System.out.println("VIP用户:8折+满100减20,折后价:" + tempPrice); return tempPrice; } }
|
第三步,定义一个使用策略的上下文,它持有策略对象,能够根据不同策略计算折扣
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class OrderContext { private DiscountStrategy discountStrategy;
public OrderContext(DiscountStrategy discountStrategy) { this.discountStrategy = discountStrategy; }
public void setDiscountStrategy(DiscountStrategy discountStrategy) { this.discountStrategy = discountStrategy; }
public double calculateFinalPrice(double originalPrice) { return discountStrategy.calculate(originalPrice); } }
|
下面的代码演示了客户端调用折扣策略的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class ShoppingCart { public static void main(String[] args) { double goodsPrice = 150.0;
OrderContext order = new OrderContext(new NormalUserDiscount()); order.calculateFinalPrice(goodsPrice);
order.setDiscountStrategy(new MemberDiscount()); order.calculateFinalPrice(goodsPrice);
order.setDiscountStrategy(new VipDiscount()); order.calculateFinalPrice(goodsPrice);
order.setDiscountStrategy(new HolidayDiscount()); order.calculateFinalPrice(goodsPrice); } }
|
有了策略模式,那么我们就可以根据需求增加不同的策略,比如针对某个促销定义一个新的策略,我们只需要增加一个策略对象即可
1 2 3 4 5 6 7 8 9
| class HolidayDiscount implements DiscountStrategy { @Override public double calculate(double originalPrice) { double discountedPrice = originalPrice * 0.7; System.out.println("节日促销:7折,折后价:" + discountedPrice); return discountedPrice; } }
|
使用策略模式的优势如下:
- 消除条件判断:避免使用
if-else或switch判断用户类型来选择折扣(传统方式会导致代码臃肿且难维护)。
- 动态切换:支持运行时根据情况切换策略(如用户升级为 VIP 后立即应用 VIP 折扣)。
- 易于扩展:比如上面的代码中,新增折扣策略只需实现
DiscountStrategy接口,无需修改现有代码(符合开闭原则)。
- 算法复用:不同订单可以共享同一个策略实例(如所有会员都使用
MemberDiscount)。