24.设计模式-Strategy(策略)
一、模式定义与核心价值
策略模式是一种行为型设计模式,其核心目标是定义一系列算法族,并将每个算法封装为独立对象,使其可动态替换。该模式通过解耦算法定义与使用逻辑,实现以下核心价值:
- 消除条件分支:避免大量
if-else或switch-case硬编码,提升代码可维护性(如电商促销活动的多算法切换) - 开放扩展性:新增算法无需修改现有代码,符合开闭原则(如导航系统中新增骑行路线策略)
- 运行时灵活性:客户端可动态选择算法(如投资系统中的价值投资、成长投资策略切换)
经典场景:
- 支付网关的多渠道计费规则(微信支付、支付宝的费率计算)
- 游戏角色的技能释放策略(普攻、连招、必杀技)
- 数据压缩格式选择(ZIP、RAR、7z算法的动态切换)
二、模式组成与UML类图
核心角色
- Strategy(策略接口):
-
- 定义算法的公共接口(如
calculate())
- 定义算法的公共接口(如
- ConcreteStrategy(具体策略):
-
- 实现接口的具体算法(如满减策略、折扣策略)
- Context(上下文):
-
- 持有策略引用,通过接口调用算法(如订单结算系统)
UML类图
classDiagram
class Context {
-strategy: Strategy
+setStrategy(Strategy)
+executeStrategy()
}
interface Strategy {
<<interface>>
+execute()
}
class ConcreteStrategyA {
+execute()
}
class ConcreteStrategyB {
+execute()
}
Context --> Strategy
Strategy <|.. ConcreteStrategyA
Strategy <|.. ConcreteStrategyB

三、代码实现示例
场景:电商促销系统实现动态折扣策略(满减、百分比折扣、会员专属折扣)
1. 策略接口与实现
// 抽象策略接口
interface DiscountStrategy {
double calculateDiscount(double originalPrice);
}
// 具体策略:满减策略
class FullReductionStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double price) {
return price > 200 ? price - 50 : price; // 满200减50
}
}
// 具体策略:八折策略
class PercentageDiscountStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double price) {
return price * 0.8;
}
}
2. 上下文类
class ShoppingCart {
private DiscountStrategy strategy;
public void setStrategy(DiscountStrategy strategy) {
this.strategy = strategy;
}
public double checkout(double originalPrice) {
if (strategy == null) throw new IllegalStateException("未选择折扣策略");
return strategy.calculateDiscount(originalPrice);
}
}
3. 客户端调用
public class Client {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
// 动态切换策略
cart.setStrategy(new FullReductionStrategy());
System.out.println("满减后价格:" + cart.checkout(250)); // 输出200.0
cart.setStrategy(new PercentageDiscountStrategy());
System.out.println("八折后价格:" + cart.checkout(250)); // 输出200.0
}
}
四、工业级源码应用
- Java集合框架
-
Comparator接口是典型策略模式,通过实现compare()方法定义不同排序策略(如Collections.sort()的定制排序)
- Spring框架
-
- 资源加载策略:
ResourceLoader使用Resource策略接口支持类路径、文件系统、URL等多种资源加载方式 - 事务管理:
PlatformTransactionManager定义事务策略,DataSourceTransactionManager和JpaTransactionManager为具体实现
- 资源加载策略:
- 智能合约开发
-
- DeFi协议中动态定价机制(如线性定价与二次曲线定价策略的动态切换)
interface IPricingStrategy {
function calculatePrice(uint256 amount) external view returns (uint256);
}
contract TokenSale {
IPricingStrategy public strategy;
function setStrategy(address _strategy) external onlyOwner {
strategy = IPricingStrategy(_strategy);
}
}
- Android UI系统
-
- 动画插值器(
TimeInterpolator):LinearInterpolator、AccelerateDecelerateInterpolator等策略实现动画速率曲线
- 动画插值器(
- 机器学习框架
-
- Scikit-learn的模型评估模块:
scoring参数接受不同评估策略(准确率、F1值、AUC等)
- Scikit-learn的模型评估模块:
五、模式对比与选型建议
| 对比维度 | 策略模式 | 工厂模式 |
|---|---|---|
| 核心目标 | 算法行为的动态切换 | 对象创建的解耦 |
| 扩展方向 | 横向扩展算法族 | 纵向扩展产品族 |
| 典型应用 | 支付费率计算、路由规划 | 数据库连接池、日志器 |
最佳实践建议:
- 识别变化点:将频繁变更的算法逻辑剥离为策略类(如网页3的导航路线规划场景)
- 策略轻量化:避免策略类携带过多状态,优先设计无状态策略对象
- 结合注解:Spring项目中可用
@Qualifier注解动态注入策略实现
总结
策略模式通过算法封装与动态委派的机制,在电商促销、金融交易、智能合约等场景展现了强大的灵活性。其与工厂模式、模板方法模式的组合使用(如网页9的C++交易系统案例),更能构建出高扩展性的系统架构。开发者应重点识别业务中的高频变更算法,通过策略模式实现业务规则与执行逻辑的优雅解耦。

浙公网安备 33010602011771号