JavaScript程序设计模式小技巧——策略模式,快看快用!!!

JavaScript程序设计模式小技巧——策略模式,快看快用!!!
最新回答
予情

2026-10-22 09:46:50

策略模式是 JavaScript 中一种将算法封装为独立对象并可相互替换的设计模式,通过分离变化部分与不变逻辑,提升代码的灵活性、可维护性和复用性。 以下是具体实现技巧与案例解析:

一、核心概念

策略模式由两部分组成:

  • 策略类:封装具体算法(如不同绩效的奖金计算规则)。
  • 环境类(Context):接收请求并委托给策略类执行(如 calcBonus 函数根据绩效等级调用对应策略)。
二、典型案例:奖金计算1. 传统实现(问题明显)var calcBonus = function(level, salary) { if (level === "S") return salary * 4; if (level === "A") return salary * 3; if (level === "B") return salary * 2;};

缺点:

  • 函数臃肿,新增绩效等级需修改函数体,违反开放-封闭原则。
  • 复用性差,其他场景需重复编写类似逻辑。
2. 策略模式优化// 策略类:封装各绩效算法var strategies = { S: function(salary) { return salary * 4; }, A: function(salary) { return salary * 3; }, B: function(salary) { return salary * 2; }};// 环境类:委托执行var calcBonus = function(level, salary) { return strategies[level](salary);};

优势:

  • 扩展性:新增绩效等级(如 C: salary * 1)只需扩展 strategies 对象,无需修改 calcBonus。
  • 可维护性:算法逻辑独立,便于单独调试与优化。
  • 复用性:其他场景(如季度奖计算)可直接复用 strategies。
三、进阶案例:表单验证1. 传统实现(问题同上)function submit() { let { username, password, tel } = infoForm; if (!username) { Toast("用户名不能为空"); return false; } if (password.length < 6) { Toast("密码长度不足"); return false; } if (!/^1[358]d{9}$/.test(tel)) { Toast("手机号格式错误"); return false; }}2. 策略模式优化

步骤 1:定义验证策略

var strategies = { isEmpty: function(val, msg) { if (!val) return msg; }, minLength: function(val, length, msg) { if (val.length < length) return msg; }, isTel: function(val, msg) { if (!/^1[358]d{9}$/.test(val)) return msg; }};

步骤 2:实现验证器(环境类)

class Validator { constructor() { this.cache = []; } add(attr, rule, msg) { const ruleArr = rule.split(":"); this.cache.push(() => { const strategy = ruleArr.shift(); ruleArr.unshift(attr); ruleArr.push(msg); return strategies[strategy].apply(attr, ruleArr); }); } start() { for (const validator of this.cache) { const msg = validator(); if (msg) return msg; } }}

步骤 3:配置验证规则并执行

function validFn() { const validator = new Validator(); const { username, password, tel } = infoForm; validator.add(username, "isEmpty", "用户名不能为空"); validator.add(password, "minLength:6", "密码长度不足"); validator.add(tel, "isTel", "手机号格式错误"); return validator.start();}function submit() { const msg = validFn(); if (msg) { Toast(msg); return false; } console.log("验证通过");}四、动态扩展规则

若需为同一字段配置多条规则(如用户名同时检查非空与长度),可修改 Validator.add 方法支持数组参数:

class Validator { add(attr, rules) { rules.forEach(rule => { const ruleArr = rule.strategy.split(":"); const msg = rule.msg; this.cache.push(() => { const strategy = ruleArr.shift(); ruleArr.unshift(attr); ruleArr.push(msg); return strategies[strategy].apply(attr, ruleArr); }); }); }}// 使用示例validator.add(username, [ { strategy: "isEmpty", msg: "用户名不能为空" }, { strategy: "minLength:6", msg: "用户名长度不足" }]);五、策略模式的核心价值
  1. 封装变化:将易变的算法逻辑隔离在策略类中。
  2. 委托机制:环境类通过委托调用策略,避免条件分支。
  3. 多态性:不同策略对同一请求提供不同实现(如 strategies.S 与 strategies.A)。
  4. 符合开放-封闭原则:扩展新策略无需修改现有代码。
六、适用场景
  • 算法需要频繁切换(如压缩算法选择 ZIP/GZIP)。
  • 存在多个相似类仅行为不同(如不同支付方式的手续费计算)。
  • 需要动态加载策略的场景(如根据用户权限显示不同操作按钮)。

通过策略模式,可将复杂逻辑拆解为独立、可替换的模块,显著提升代码的可维护性与扩展性。