策略模式(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);
  }
}
相关推荐
像风一样自由20202 小时前
HTML与JavaScript:构建动态交互式Web页面的基石
前端·javascript·html
aiprtem3 小时前
基于Flutter的web登录设计
前端·flutter
浪裡遊3 小时前
React Hooks全面解析:从基础到高级的实用指南
开发语言·前端·javascript·react.js·node.js·ecmascript·php
why技术3 小时前
Stack Overflow,轰然倒下!
前端·人工智能·后端
GISer_Jing3 小时前
0704-0706上海,又聚上了
前端·新浪微博
止观止3 小时前
深入探索 pnpm:高效磁盘利用与灵活的包管理解决方案
前端·pnpm·前端工程化·包管理器
whale fall3 小时前
npm install安装的node_modules是什么
前端·npm·node.js
烛阴3 小时前
简单入门Python装饰器
前端·python
袁煦丞4 小时前
数据库设计神器DrawDB:cpolar内网穿透实验室第595个成功挑战
前端·程序员·远程工作
天天扭码4 小时前
从图片到语音:我是如何用两大模型API打造沉浸式英语学习工具的
前端·人工智能·github