策略模式(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);
  }
}
相关推荐
知识分享小能手3 小时前
微信小程序入门学习教程,从入门到精通,微信小程序常用API(上)——知识点详解 + 案例实战(4)
前端·javascript·学习·微信小程序·小程序·html5·微信开放平台
清灵xmf3 小时前
CSS field-sizing 让表单「活」起来
前端·css·field-sizing
文火冰糖的硅基工坊3 小时前
[光学原理与应用-480]:《国产检测设备对比表》
前端·人工智能·系统架构·制造·半导体·产业链
excel4 小时前
Qiankun 子应用生命周期及使用场景解析
前端
weixin_446260854 小时前
Django - 让开发变得简单高效的Web框架
前端·数据库·django
蓝莓味的口香糖4 小时前
【JS】什么是单例模式
开发语言·javascript·单例模式
ObjectX前端实验室5 小时前
【react18原理探究实践】异步可中断 & 时间分片
前端·react.js
SoaringHeart5 小时前
Flutter进阶:自定义一个 json 转 model 工具
前端·flutter·dart
努力打怪升级5 小时前
Rocky Linux 8 远程管理配置指南(宿主机 VNC + KVM 虚拟机 VNC)
前端·chrome
brzhang5 小时前
AI Agent 干不好活,不是它笨,告诉你一个残忍的现实,是你给他的工具太难用了
前端·后端·架构