前端开发中的策略模式——告别 if-else 的优雅之道

策略模式是前端开发中最实用的设计模式之一。它不复杂,却能显著提升代码的可维护性。本文从最典型的表单校验场景出发,给出策略模式的完整实现。

一、一个被 if-else 淹没的场景

假设你在做后台管理系统的表单,需要校验不同类型的字段:邮箱、手机号、密码、身份证号等。最常见的写法是这样:

javascript 复制代码
function validate(value, type) {
  if (type === 'email') {
    return /\S+@\S+\.\S+/.test(value) ? '' : '邮箱格式错误';
  } else if (type === 'phone') {
    return /^1[3-9]\d{9}$/.test(value) ? '' : '手机号格式错误';
  } else if (type === 'password') {
    return value.length >= 6 ? '' : '密码至少6位';
  } else if (type === 'idCard') {
    // 身份证校验逻辑...
  }
  return '';
}

问题很明显:新增一种校验类型,就要改动这个函数。随着业务发展,这个函数会越来越长,每次改动都可能影响已有逻辑。这就是策略模式要解决的问题。

二、策略模式的核心思想

定义一系列算法,把它们封装成可互换的策略函数,用配置对象代替条件分支 。调用方根据场景选择策略,而不是用 if-else 硬编码分支逻辑。

用在表单校验上:

javascript 复制代码
// 1. 把每种校验规则封装成独立策略
const validators = {
  required: (val) => (val && val.trim() ? '' : '必填'),
  email: (val) => (/^\S+@\S+\.\S+$/.test(val) ? '' : '邮箱格式错误'),
  phone: (val) => (/^1[3-9]\d{9}$/.test(val) ? '' : '手机号格式错误'),
  minLength: (min) => (val) => (val.length >= min ? '' : `最少${min}位`),
};

// 2. 通用校验器------策略调度
function validate(value, rules) {
  for (const rule of rules) {
    const fn = typeof rule === 'function' ? rule : validators[rule];
    const error = fn(value);
    if (error) return error;
  }
  return '';
}

使用:

javascript 复制代码
validate('hello@test.com', ['required', 'email']);            // ''
validate('hi', ['required', 'email']);                         // '邮箱格式错误'
validate('abc', ['required', validators.minLength(6)]);        // '最少6位'

新增任何校验规则,只需要在 validators 对象上加一个方法,完全不用改动 validate 函数。这就是策略模式的价值:对扩展开放,对修改关闭

在 React 中配合 Ant Design 使用时同样清晰:

tsx 复制代码
<Form.Item
  name="email"
  rules={[{ validator: (_, val) => validators.email(val) }]}
>
  <Input />
</Form.Item>

三、另外两个高频应用场景

1. 状态映射------数字变 UI

接口返回订单状态 012,页面需要展示不同颜色的标签。不用策略模式时,往往在 render 里写一堆三元表达式。改用配置对象:

javascript 复制代码
const ORDER_STATUS_MAP = {
  0: { text: '待支付', color: 'orange' },
  1: { text: '已支付', color: 'green' },
  2: { text: '已取消', color: 'gray' },
};

function getStatusConfig(status) {
  return ORDER_STATUS_MAP[status] ?? { text: '未知', color: 'gray' };
}
tsx 复制代码
// React 表格中
render: (status) => {
  const config = getStatusConfig(status);
  return <Tag color={config.color}>{config.text}</Tag>;
}

日志级别、用户角色、通知类型等场景同理------用配置对象统一管理映射关系,新增状态只需加一行。

2. 环境适配------不同环境不同行为

开发环境需要打印日志到控制台,生产环境需要上报到 Sentry。策略模式可以配合构建工具的 Tree Shaking,在打包时只保留当前环境需要的代码:

javascript 复制代码
// loggers/dev.ts
export const logger = {
  error: (msg) => console.error(msg),
  warn: (msg) => console.warn(msg),
};

// loggers/prod.ts
export const logger = {
  error: (msg, extra) => Sentry.captureMessage(msg, { extra }),
  warn: () => {},
};
javascript 复制代码
// 动态导入,构建时只保留一个文件
const logger = await import(`./loggers/${import.meta.env.MODE}.ts`);
logger.error('出错了');

环境切换、支付渠道、地图 SDK 选择------凡是需要根据某个条件选择不同处理方式的场景,都可以用策略模式。

四、总结

策略模式是最实用的前端设计模式之一。它用配置对象代替条件分支,让代码对扩展开放、对修改关闭。在前端开发中,它最常见的落地场景包括:

  • 表单校验:不同字段、不同规则用策略函数组合
  • 状态映射:数字/枚举 → UI 组件的映射表
  • 环境适配:开发、测试、生产的不同行为策略
  • 格式化器:日期、金额、文件大小的多种格式化策略

当你发现自己在写大量 if-elseswitch 来决定"怎么处理"时,就是策略模式该上场的时候。把条件分支替换成配置对象,把每种逻辑封装成独立策略,代码结构会立刻清晰起来。

相关推荐
不坑老师1 小时前
怎么在Word中制作汉字书写笔顺——不坑盒子汉字笔顺步骤在小学低段识字教学中的应用
前端·数据库·人工智能·word·excel·office
许我半盏清茶1 小时前
基于 Ollama + Vectra + MCP 从零搭建本地 RAG 知识库
javascript·人工智能·mcp
anyup1 小时前
30 分钟用 Trae Work + 魔珐星云做出会讲故事的 AI 3D 具身交互智能数字人
前端·ai编程·trae
IT_陈寒1 小时前
Vue的响应式竟然在这常见操作下失效了
前端·人工智能·后端
你怎么知道我是队长1 小时前
JavaScript 事件介绍
开发语言·前端·javascript
宇晨T2 小时前
从零搭建企业级Web服务:Shell脚本 + LNMP + Docker 实战指南
前端·docker·容器
禅思院2 小时前
AI对话前端从入门到崩溃:一个长对话引发的五层优化战争【四】
前端·架构·前端框架
恋猫de小郭2 小时前
Flutter Windows 开始支持 Impeller ,还修复了多窗口 bug
android·前端·flutter
柳杉2 小时前
没写一行代码!我用 ChatGPT 5.6 (Sol) 做了一个智慧充电站 3D 大屏
前端·chatgpt·数据可视化