目录
[2.1 模式结构](#2.1 模式结构)
[2.2 实现案例](#2.2 实现案例)
1、核心思想
目的:将算法(行为)抽象出来作为一系列策略类,使他们可以相互替换,使系统拥有"可插拔"扩展的能力。
举例:
1> 游戏卡带:可插卡式的游戏机
2> 计算器:固定是两个输入和一个输出的结构,不同的算法实现类(加、减、乘、除等)
3> 万能的USB口:不同设备捕获数据(如键盘设备捕获的是键盘指令数据,鼠标设备捕获的是坐标与点击指令数据,摄像头设备捕获的是视频流数据)
2、实现方式
2.1 模式结构
三个核心角色:
- Strategy(策略接口):定义通用的策略规范标准,包含在系统环境中并声明策略接口标准。
- ConcreteStrategyA、ConcreteStrategyB、ConcreteStrategyC......(策略实现):实现了策略接口的策略实现类,可以有多种不同的策略实现,但都得符合策略接口定义的规范。
- Context(系统环境):包含策略接口引用的系统环境,对外提供更换策略实现的方法setStrategy()以及执行策略的方法executeStrategy(),其本身并不关心执行的是哪种策略实现。

2.2 实现案例
举例:电商促销策略
java
// 策略接口
public interface DiscountStrategy {
double applyDiscount(double price);
}
// 具体策略:无折扣
public class NoDiscount implements DiscountStrategy {
@Override
public double applyDiscount(double price) {
return price;
}
}
// 具体策略:8折
public class TwentyPercentOff implements DiscountStrategy {
@Override
public double applyDiscount(double price) {
return price * 0.8;
}
}
// 具体策略:满300减50
public class FullReduction implements DiscountStrategy {
@Override
public double applyDiscount(double price) {
return price >= 300 ? price - 50 : price;
}
}
// 上下文类(订单)
public class Order {
private DiscountStrategy strategy;
public void setStrategy(DiscountStrategy strategy) {
this.strategy = strategy;
}
public double checkout(double price) {
return strategy.applyDiscount(price);
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Order order = new Order();
order.setStrategy(new TwentyPercentOff());
System.out.println("最终价格:" + order.checkout(400)); // 输出 320.0
}
}
3、优缺点分析
优点:
-
开闭原则:新增算法时无需修改现有代码,只需添加新策略类。
-
解耦算法与业务逻辑:算法独立于客户端,易于扩展和维护。
-
消除条件分支 :避免代码中复杂的
if-else
逻辑。 -
复用性:不同策略可被多个客户端共享使用。
缺点:
-
类数量增加:每个策略需要一个类,可能导致类膨胀。
-
客户端需了解策略差异:客户端需要知道不同策略的适用场景。
-
性能开销:频繁切换策略可能带来对象创建和销毁的开销(可通过享元模式优化)。
4、适用场景
-
多种算法需要动态切换
- 例如:支付方式(支付宝、微信、银行卡)、排序算法(快速排序、归并排序)。
-
需要隐藏算法实现细节
- 例如:加密算法(AES、RSA)、数据压缩(ZIP、RAR)。
-
替代复杂的条件分支
- 例如:电商促销策略(满减、折扣、赠品)。
-
系统需要灵活扩展新算法
- 例如:机器学习模型的不同训练策略。
5、优化技巧
策略对象的创建优化
- 若策略无状态,可复用为单例(如
Collections.sort()
中的Comparator
)。
结合Lambda简化代码
- 在支持函数式编程的语言(如Java 8+),可用Lambda替代简单策略类。
java
context.setStrategy(data -> System.out.println("Lambda策略处理:" + data));
策略枚举化
- 对于有限的策略集合,可使用枚举类实现策略模式。
java
public enum DiscountType implements DiscountStrategy {
NO_DISCOUNT { /* 实现方法 */ },
TWENTY_PERCENT { /* 实现方法 */ };
}