算法的「锦囊妙计」:策略模式的百宝箱艺术

168 阅读3分钟

算法的「锦囊妙计」:策略模式的百宝箱艺术


一、当代码开始「见招拆招」

想象这样的武侠世界:
黄蓉随身携带打狗棒、软猬甲、峨眉刺,遇敌时信手切换武器;
诸葛亮北伐时打开不同锦囊,时而火攻时而水淹;
吃鸡游戏中,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 流水线工人:锦囊与流水线的区别

维度策略模式工厂模式
核心目的动态切换算法统一创建对象
关注点行为的多样性对象的诞生方式
典型应用支付方式选择数据库连接创建
调用方式主动执行算法被动获取对象
现实类比诸葛亮的锦囊富士康的流水线

五、代码江湖的兵法应用

  1. 支付系统:支付宝/微信/银联支付策略一键切换
  2. 导航软件:驾车/步行/骑行不同路径算法
  3. 游戏AI:普通模式/困难模式/Boss战的不同行为树
  4. 排序算法:根据数据量选择快排/归并排序
  5. 促销活动:满减/折扣/赠品等营销策略

经典案例

// Java的Comparator就是策略模式的典范
Collections.sort(list, (a, b) -> b.compareTo(a)); // 传入不同比较策略

六、防走火入魔指南(最佳实践)

  1. 策略无状态

    // 好的策略应该像纯净水
    class GoodStrategy implements Strategy {
        // 不包含成员变量
        void execute() { /* 只依赖输入参数 */ }
    }
    
  2. 策略工厂化

    // 用枚举管理策略
    enum StrategyType {
        SWORD(new SwordStrategy()),
        STAFF(new StaffStrategy());
        
        private Strategy strategy;
        // getter...
    }
    
  3. 避免策略爆炸

    当策略超过10个时:
    1. 用策略组合代替单一策略
    2. 引入策略层级结构
    3. 考虑函数式接口
    
  4. Lambda简化

    // JDK8+可以用Lambda代替策略类
    context.execute(data, x -> x * 0.9); // 打折策略
    
  5. 依赖注入

    // Spring中自动注入策略集合
    @Autowired
    private Map<String, Strategy> strategyMap;
    

七、江湖生存总结

策略模式让代码成为智能军师:

  • :用于需要灵活切换算法的场景
  • :保持策略的单一职责
  • 不要:让策略知晓Context细节
  • 不要:创建生命周期过长的策略

当你在淘宝选择不同优惠券时,请想起策略模式——那个在后台默默切换计算方式的隐形军师!