策略模式是一种行为型设计模式,其核心在于将算法或业务逻辑封装成独立的策略对象,通过组合或替换策略对象来动态改变程序行为。以下是关键要点解析:
1. 策略模式的核心思想- 封装算法:将不同逻辑(如等级计算、表单验证)拆分为独立的策略对象,避免冗长的条件分支(如if-else/switch)。
- 动态切换:运行时通过传入不同策略对象来切换算法,符合开闭原则(对扩展开放,对修改关闭)。
- 解耦与复用:策略对象与使用逻辑分离,提升代码可维护性和可测试性。
2. 代码示例解析场景一:游戏等级经验计算原始问题:getExperience函数通过多个if判断等级,硬编码逻辑导致扩展困难。
策略模式改造:
- 策略对象:将等级规则封装为strategy对象,每个等级对应一个纯函数。
- 上下文函数:getExperience接收策略对象和参数,动态调用对应策略。
const strategy = { 'S': (exp) => 4 * exp, 'A': (exp) => 3 * exp, 'B': (exp) => 2 * exp};function getExperience(strategy, level, exp) { return strategy[level] ? strategy[level](exp) : exp;}优势:
- 新增等级只需扩展strategy对象,无需修改getExperience。
- 逻辑清晰,符合单一职责原则。
场景二:Vue指令更新器Vue的compileUtil使用策略模式处理不同指令(如v-text、v-html):
- 策略对象:compileUtil中的方法对应不同指令的更新逻辑。
- 动态调用:通过指令名称(如text、html)映射到对应策略函数。
var compileUtil = { text: function(node, vm, exp) { /* 更新文本逻辑 */ }, html: function(node, vm, exp) { /* 更新HTML逻辑 */ }, bind: function(node, vm, exp, dir) { var updaterFn = updater[dir + 'Updater']; updaterFn(node, this._getVMVal(vm, exp)); }};优势:
场景三:表单验证原始问题:传统表单验证依赖多层if-else,难以维护和复用。
策略模式改造:
- 策略对象:strategies定义验证规则(如非空、长度限制)。
- 验证器类:Validator动态组合策略,通过add方法添加规则,validate执行校验。
const strategies = { noEmpty: (value, msg) => value === '' ? msg : '', minLength: (value, len, msg) => value.length < len ? msg : ''};class Validator { constructor() { this.cache = []; } add(dom, rules) { rules.forEach(rule => { this.cache.push(() => { const [name, param] = rule.rule.split(':'); return strategies[name](dom.value, param, rule.errMsg); }); }); } validate() { return this.cache.some(fn => fn()); // 返回第一条错误信息 }}优势:
- 自定义规则只需扩展strategies对象。
- 验证逻辑与UI解耦,可复用于不同表单。
3. 策略模式的适用场景- 多分支条件逻辑:如游戏等级、权限校验、折扣计算等。
- 动态算法切换:如排序算法(冒泡、快速排序)、支付方式(支付宝、微信)。
- 消除重复代码:将分散的相似逻辑集中到策略对象中。
4. 与其他模式的对比- 工厂模式:工厂关注对象创建,策略关注行为封装。
- 状态模式:状态模式通过状态对象改变行为,策略模式直接替换算法。
5. 总结策略模式通过对象化算法,将条件分支转化为策略对象的组合,显著提升代码的可扩展性和可读性。在JavaScript中,尤其适合处理动态行为切换的场景(如表单验证、视图更新)。实际开发中,可结合ES6的类、模块化等特性进一步优化策略管理。