策略模式(Strategy Pattern)深入解析与实战应用

策略模式是一种常见的行为型设计模式,常用于替代大量冗余的 if-elseswitch-case 结构。它通过将一系列可互换的策略(行为)封装起来,使代码结构更清晰、可扩展性更强。

一、什么是策略模式?

策略模式(Strategy Pattern) 是指将一组算法或操作逻辑抽象为独立的"策略对象",根据上下文条件选择某一种策略执行。

一句话概括:把繁杂的 if-else 判断逻辑,变成"查表执行"。

二、策略模式结构图

plaintext 复制代码
┌────────────┐
│  Context   │ ← 运行环境,持有策略并调用
└────┬───────┘
     │
     ▼
┌────────────┐
│ Strategy A │ ← 实现某个行为
└────────────┘
┌────────────┐
│ Strategy B │ ← 实现另一个行为
└────────────┘

在 JavaScript/TypeScript 中,我们通常用对象映射(Map)来实现策略模式。

三、为什么要使用策略模式?

问题 策略模式解决方案
逻辑混乱 将不同逻辑解耦封装
if/else 重复臃肿 使用映射对象替代判断
新增/修改逻辑易出错 可扩展、遵循开闭原则
单元测试困难 策略单元独立、易测试

四、策略模式实战案例

✅ 1. 表单校验策略

ts 复制代码
const validateMap = {
  email: (val: string) => /\S+@\S+\.\S+/.test(val),
  phone: (val: string) => /^1\d{10}$/.test(val),
  username: (val: string) => val.length >= 3
};

function validate(type: string, value: string) {
  const fn = validateMap[type];
  return fn ? fn(value) : false;
}

✅ 2. Vue

动态视图策略

ts 复制代码
// strategies.ts
export const renderMap = {
  list: () => <ListView />,
  card: () => <CardView />,
  table: () => <TableView />
}
vue 复制代码
<template>
  <component :is="renderMap[viewMode]" />
</template>

🔁 五、从 if-else 到策略模式

原始写法(冗余):

ts 复制代码
function parseFile(type, content) {
  if (type === 'json') return JSON.parse(content)
  if (type === 'xml') return parseXML(content)
  if (type === 'csv') return parseCSV(content)
  throw new Error('Unknown type')
}

策略模式写法(优雅):

ts 复制代码
const parsers = {
  json: JSON.parse,
  xml: parseXML,
  csv: parseCSV
}

function parseFile(type: string, content: string) {
  const fn = parsers[type]
  if (!fn) throw new Error('Unknown type')
  return fn(content)
}

🧠 六、策略模式适用场景

  • 多分支逻辑(if/else 或 switch)

  • 规则判断:权限控制、表单验证、日志等级等

  • 插件架构:支付方式、导出格式等

  • 动态行为切换:主题切换、布局切换、组件渲染等

七、策略模式的进阶技巧

技巧 示例
支持注册/注销策略 StrategyMap.register('new', fn)
结合工厂模式 动态生成策略对象
封装为类或插件 统一维护,提升复用性
与配置驱动结合 使用配置文件/后端数据决定策略行为

八、与其他设计模式的区别

模式 相同点 区别
工厂模式 都封装行为创建 工厂关注对象创建,策略关注逻辑执行
状态模式 都有行为切换 状态模式强调状态变化,策略是行为选择
命令模式 都可执行操作 命令模式可撤销/排队,策略更偏向选择

✅ 九、总结

策略模式具有以下优点:

  • ✅ 解耦逻辑,清晰可读

  • ✅ 易于扩展,符合开闭原则

  • ✅ 易于测试,策略函数天然可单测

  • ✅ 非常适合动态渲染与业务逻辑分发

十、推荐封装方式(TypeScript 示例)

ts 复制代码
type StrategyFn = (args?: any) => any;

class StrategyManager {
  private strategies: Record<string, StrategyFn> = {};

  register(key: string, fn: StrategyFn) {
    this.strategies[key] = fn;
  }

  execute(key: string, args?: any) {
    const fn = this.strategies[key];
    if (!fn) throw new Error(`No strategy for key: ${key}`);
    return fn(args);
  }
}
相关推荐
前端AK君15 小时前
React中台系统如何嵌入到业务系统中
前端
Slice_cy16 小时前
不定高虚拟列表
前端
前端AK君16 小时前
React组件库如何在vue项目中使用
前端
Moonbit16 小时前
MoonBit 再次走进清华:张宏波受邀参加「思源计划」与「程序设计训练课」
前端·后端·编程语言
RestCloud16 小时前
一站式数据集成:iPaaS 如何让开发者和业务人员都满意?
前端·后端·架构
li357416 小时前
React 核心 Hook 与冷门技巧:useReducer、useEffect、useRef 及 is 属性全解析
前端·javascript·react.js
菜市口的跳脚长颌16 小时前
Web3 基础
前端
快乐是Happy16 小时前
分享一个非常实用的防止重复提交操作
前端·javascript
王蛋11116 小时前
前端工作问题或知识记录
前端·npm·node.js
可子是我的小猫16 小时前
【JS】模块(二)
javascript