算法的「锦囊妙计」:策略模式的百宝箱艺术
一、当代码开始「见招拆招」
想象这样的武侠世界:
黄蓉随身携带打狗棒、软猬甲、峨眉刺,遇敌时信手切换武器;
诸葛亮北伐时打开不同锦囊,时而火攻时而水淹;
吃鸡游戏中,98K、平底锅、手雷根据战况轮番登场...
这就是策略模式的精髓——把算法装进「锦囊」,让代码像武林高手般灵活切换招式,面对不同需求随时亮出绝活!
二、军师的兵法图谱(UML图)
┌─────────────┐ ┌─────────────┐
│ Context │<>───────>│ Strategy │
├─────────────┤ ├─────────────┤
│ +execute() │ │ +algorithm()│
└──────△──────┘ └──────△──────┘
│ │
┌──────┴──────┐ ┌──────┴──────┐
│ Concrete │ │ Concrete │
│ Context │ │ StrategyA │
└─────────────┘ └─────────────┘
- 主帅(Context):持策略的决策者
- 兵法总纲(Strategy):定义算法接口
- 锦囊妙计(ConcreteStrategy):具体计策实现
三、代码江湖的比武大会(场景实战)
1. 创建兵法库(策略接口)
// 江湖通用武功秘籍
interface AttackStrategy {
void attack(String enemy); // 见招拆招的算法
}
2. 编写各派绝学(具体策略)
// 峨眉剑法:精准点杀
class SwordStrategy implements AttackStrategy {
@Override
public void attack(String enemy) {
System.out.println("🗡️ 剑出如龙,直取" + enemy + "咽喉!");
}
}
// 少林棍法:范围打击
class StaffStrategy implements AttackStrategy {
@Override
public void attack(String enemy) {
System.out.println("🦯 横扫千军,震退所有" + enemy + "!");
}
}
// 唐门暗器:远程偷袭
class DartStrategy implements AttackStrategy {
@Override
public void attack(String enemy) {
System.out.println("🎯 暴雨梨花针瞬间覆盖" + enemy + "!");
}
}
3. 打造智能武器匣(上下文)
class WeaponBox {
private AttackStrategy strategy;
// 切换武器
public void switchWeapon(AttackStrategy strategy) {
this.strategy = strategy;
}
// 发动攻击
public void executeAttack(String enemy) {
if (strategy == null) {
System.out.println("⚠️ 请先选择武器!");
return;
}
strategy.attack(enemy);
}
}
4. 江湖实战演练
public class JiangHu {
public static void main(String[] args) {
WeaponBox box = new WeaponBox();
// 遭遇单个Boss
box.switchWeapon(new SwordStrategy());
box.executeAttack("金轮法王"); // 🗡️剑出如龙...
// 被小兵包围
box.switchWeapon(new StaffStrategy());
box.executeAttack("蒙古士兵"); // 🦯横扫千军...
// 远程偷袭
box.switchWeapon(new DartStrategy());
box.executeAttack("蒙古弓箭手"); // 🎯暴雨梨花针...
}
}
四、策略模式 vs 流水线工人:锦囊与流水线的区别
| 维度 | 策略模式 | 工厂模式 |
|---|---|---|
| 核心目的 | 动态切换算法 | 统一创建对象 |
| 关注点 | 行为的多样性 | 对象的诞生方式 |
| 典型应用 | 支付方式选择 | 数据库连接创建 |
| 调用方式 | 主动执行算法 | 被动获取对象 |
| 现实类比 | 诸葛亮的锦囊 | 富士康的流水线 |
五、代码江湖的兵法应用
- 支付系统:支付宝/微信/银联支付策略一键切换
- 导航软件:驾车/步行/骑行不同路径算法
- 游戏AI:普通模式/困难模式/Boss战的不同行为树
- 排序算法:根据数据量选择快排/归并排序
- 促销活动:满减/折扣/赠品等营销策略
经典案例:
// Java的Comparator就是策略模式的典范
Collections.sort(list, (a, b) -> b.compareTo(a)); // 传入不同比较策略
六、防走火入魔指南(最佳实践)
-
策略无状态:
// 好的策略应该像纯净水 class GoodStrategy implements Strategy { // 不包含成员变量 void execute() { /* 只依赖输入参数 */ } } -
策略工厂化:
// 用枚举管理策略 enum StrategyType { SWORD(new SwordStrategy()), STAFF(new StaffStrategy()); private Strategy strategy; // getter... } -
避免策略爆炸:
当策略超过10个时: 1. 用策略组合代替单一策略 2. 引入策略层级结构 3. 考虑函数式接口 -
Lambda简化:
// JDK8+可以用Lambda代替策略类 context.execute(data, x -> x * 0.9); // 打折策略 -
依赖注入:
// Spring中自动注入策略集合 @Autowired private Map<String, Strategy> strategyMap;
七、江湖生存总结
策略模式让代码成为智能军师:
- ✅ 要:用于需要灵活切换算法的场景
- ✅ 要:保持策略的单一职责
- ❌ 不要:让策略知晓Context细节
- ❌ 不要:创建生命周期过长的策略
当你在淘宝选择不同优惠券时,请想起策略模式——那个在后台默默切换计算方式的隐形军师!