目录
1、核心思想
2、实现方式
2.1 模式结构
2.2 实现案例
3、优缺点分析
4、适用场景
5、优化技巧
1、核心思想
目的:将算法(行为)抽象出来作为一系列策略类,使他们可以相互替换,使系统拥有“可插拔”扩展的能力。
举例:
1> 游戏卡带:可插卡式的游戏机
2> 计算器:固定是两个输入和一个输出的结构,不同的算法实现类(加、减、乘、除等)
3> 万能的USB口:不同设备捕获数据(如键盘设备捕获的是键盘指令数据,鼠标设备捕获的是坐标与点击指令数据,摄像头设备捕获的是视频流数据)
2、实现方式
2.1 模式结构
三个核心角色:
- Strategy(策略接口):定义通用的策略规范标准,包含在系统环境中并声明策略接口标准。
- ConcreteStrategyA、ConcreteStrategyB、ConcreteStrategyC……(策略实现):实现了策略接口的策略实现类,可以有多种不同的策略实现,但都得符合策略接口定义的规范。
- Context(系统环境):包含策略接口引用的系统环境,对外提供更换策略实现的方法setStrategy()以及执行策略的方法executeStrategy(),其本身并不关心执行的是哪种策略实现。
2.2 实现案例
举例:电商促销策略
// 策略接口
public interface DiscountStrategy {double applyDiscount(double price);
}// 具体策略:无折扣
public class NoDiscount implements DiscountStrategy {@Overridepublic double applyDiscount(double price) {return price;}
}// 具体策略:8折
public class TwentyPercentOff implements DiscountStrategy {@Overridepublic double applyDiscount(double price) {return price * 0.8;}
}// 具体策略:满300减50
public class FullReduction implements DiscountStrategy {@Overridepublic 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替代简单策略类。
context.setStrategy(data -> System.out.println("Lambda策略处理:" + data));
策略枚举化
-
对于有限的策略集合,可使用枚举类实现策略模式。
public enum DiscountType implements DiscountStrategy {NO_DISCOUNT { /* 实现方法 */ },TWENTY_PERCENT { /* 实现方法 */ };
}