JS如何实现策略模式

JS如何实现策略模式
最新回答
酒还酹江月

2020-08-12 00:39:54

在JavaScript中实现策略模式,可通过函数封装算法并动态切换,核心步骤包括定义策略对象、创建上下文类,并结合具体场景(如表单验证)灵活应用。 以下是具体实现方法及注意事项:

一、基础实现步骤
  1. 定义策略对象将不同算法封装为独立函数,存储于对象中。例如:

    const strategies = { strategyA: (data) => `${data} using strategy A`, strategyB: (data) => `${data} using strategy B`, strategyC: (data) => `${data} using strategy C`};
  2. 创建上下文类上下文类持有策略引用,并提供执行方法:

    class Context { constructor(strategy) { this.strategy = strategy; } executeStrategy(data) { return this.strategy(data); }}
  3. 动态切换与执行通过修改上下文的策略引用实现动态切换:

    const context = new Context(strategies.strategyA);console.log(context.executeStrategy("Data")); // 输出: Data using strategy Acontext.strategy = strategies.strategyB;console.log(context.executeStrategy("Data")); // 输出: Data using strategy B
二、表单验证场景应用

策略模式适合处理多变的验证规则(如邮箱、手机号、密码强度)。实现步骤如下:

  1. 定义验证策略

    const validationStrategies = { isNotEmpty: (value, errorMsg) => value === '' ? errorMsg : null, minLength: (value, length, errorMsg) => value.length < length ? errorMsg : null, isMobile: (value, errorMsg) => !/^1[3-9]d{9}$/.test(value) ? errorMsg : null};
  2. 创建验证函数遍历规则并执行对应策略:

    function validate(value, rules) { for (const rule of rules) { const strategy = validationStrategies[rule.strategy]; const args = [value, ...(rule.args || []), rule.errorMsg]; const error = strategy.apply(null, args); if (error) return error; } return null;}
  3. 使用示例

    const input = document.getElementById('input');input.addEventListener('blur', () => { const error = validate(input.value, [ { strategy: 'isNotEmpty', errorMsg: '不能为空' }, { strategy: 'minLength', args: [6], errorMsg: '不能少于6位' } ]); if (error) alert(error);});
三、避免过度设计的策略
  1. 仅在必要时使用

    适用场景:算法需动态切换或存在多种变体(如支付方式、排序算法)。

    避免场景:简单条件判断(如if-else或switch更简洁)。

  2. 保持策略简单

    策略应聚焦单一算法,复杂逻辑移至上下文类。例如:// 不推荐:策略中包含业务逻辑const badStrategy = (data) => { if (data.type === 'A') return processA(data); // 业务逻辑侵入策略 else return processB(data);};

  3. 考虑替代方案

    简单函数映射:适用于静态条件与函数的映射。const actions = { typeA: () => console.log("Action A"), typeB: () => console.log("Action B")};const type = "typeA";actions[type]?.(); // 执行对应函数

四、结合工厂模式提升灵活性

通过工厂模式集中管理策略创建,分离策略生成与使用逻辑:

  1. 定义策略工厂

    const strategyFactory = { createStrategy: (type) => { switch (type) { case 'A': return (data) => `${data} using strategy A`; case 'B': return (data) => `${data} using strategy B`; default: return null; } }};
  2. 上下文类使用工厂

    class Context { constructor(strategyType) { this.strategy = strategyFactory.createStrategy(strategyType); } executeStrategy(data) { return this.strategy?.(data) || "Strategy not found"; }}
  3. 错误处理工厂模式需处理无效策略类型,避免上下文执行时报错。

五、总结
  • 核心价值:通过函数封装算法,实现运行时动态切换,提升代码可扩展性。
  • 关键点:策略对象独立、上下文管理执行、动态切换能力。
  • 优化方向:结合TypeScript定义接口、通过工厂模式集中管理、避免过度抽象。

策略模式在JavaScript中通过函数特性得以简洁实现,合理应用可显著提升复杂场景的代码质量。