14. 策略模式(Strategy)

问题:算法有多种变体,不想用一堆 if-else 写死。

核心:把每种算法封装成独立策略,运行时可替换。

type Operation = 'add' | 'subtract' | 'multiply';
type Strategy = (a: number, b: number) => number;

const strategies: Record<Operation, Strategy> = {
  add:      (a, b) => a + b,
  subtract: (a, b) => a - b,
  multiply: (a, b) => a * b,
};

function calculate(op: Operation, a: number, b: number): number {
  return strategies[op](a, b);
}

console.log(calculate('add', 3, 5));      // 8
console.log(calculate('multiply', 3, 5)); // 15
package strategy

type Strategy func(a, b int) int

var strategies = map[string]Strategy{
  "add":      func(a, b int) int { return a + b },
  "subtract": func(a, b int) int { return a - b },
  "multiply": func(a, b int) int { return a * b },
}

func Calculate(op string, a, b int) int {
  return strategies[op](a, b)
}

实战场景

  • 支付路由:不同支付渠道有不同下单、签名、回调校验逻辑,运行时按用户选择或地区选择策略。
  • 折扣计算:满减、折扣码、会员价、阶梯价、节日活动都可以是不同价格策略。
  • 排序和推荐:列表排序按最新、热度、距离、价格、个性化推荐切换,不把逻辑写进一串 if
  • 表单校验:邮箱、手机号、身份证、密码强度、业务规则各自封装成校验策略。
  • 缓存淘汰:LRU、LFU、FIFO、TTL 是不同淘汰策略,缓存容器只负责调用当前策略。
  • 压缩和编码:上传文件时按类型选择 gzip、brotli、图片压缩或不压缩。
  • 登录方式:密码登录、短信验证码、扫码、OAuth、Passkey 都可以实现统一认证策略接口。
  • 风控规则:同一笔交易可以按低风险、高风险、新用户、大额订单选择不同审核策略。
  • 搜索匹配:精确匹配、模糊匹配、拼音匹配、语义匹配按场景切换。
  • 游戏 AI:同一角色可以在巡逻、追击、防御、逃跑之间切换决策策略。