js 策略模式深入理解


一句话概括,定义一堆行为(策略类),再用一个函数统筹(环境类),调用这些行为。

就用个对象包裹着不同行为策略,再通过一个函数去使用这些策略。

const strategies = {
  add: function(num1, num2){
	return num1 + num2;
  },
  subtract: function(num1, num2){
	return num1 - num2;
  },
  multiply: function(num1, num2){
	return num1 * num2;
  },
  divide: function(num1, num2){
	return num1 / num2;
  },
}

const calcRes = function(type, num1, num2){
  return strategies[type](num1, num2);
}

console.log(calcRes('add', 1, 2));			// 3
console.log(calcRes('multiply', 1, 2));		// 2


比if else 优雅,还有这叫什么,多态性,齐活。

多态:同一个类实例化出来的子对象,调用同一个方法可以得到不同的结果。


再举个例子加深了解,算绩效。

var calculateBonus = function( performanceLevel, salary ){
        if ( performanceLevel === 'S' ){
            return salary * 4;
        }
        if ( performanceLevel === 'A' ){
            return salary * 3;
        }
        if ( performanceLevel === 'B' ){
            return salary * 2;
        }
    };

    calculateBonus( 'B', 20000 ); // 输出:40000
    calculateBonus( 'S', 6000 ); // 输出:24000

正常可能会这么写,if-else。 但是这种写法是有缺点的。

  1. calculateBonus 函数比较庞大,包含了很多 if-else 语句

  2. calculateBonus 函数缺乏弹性,如果增加了一种新的绩效等级 C,或者想把绩效 S 的奖金 系数改为 5,那我们必须深入 calculateBonus 函数的内部实现,这是违反开放封闭原则的。

  3. 算法的复用性差

若用策略模式的思维加以重构:

class BonusStrategy {
  calculate(salary) {
    // 策略接口中的默认实现
    return 0;
  }
}
class SPerformanceStrategy extends BonusStrategy {
  calculate(salary) {
    return salary * 4;
  }
}

class APerformanceStrategy extends BonusStrategy {
  calculate(salary) {
    return salary * 3;
  }
}

class BPerformanceStrategy extends BonusStrategy {
  calculate(salary) {
    return salary * 2;
  }
}

const calculateBonus = function (performanceLevel, salary) {
  const strategies = {
    S: new SPerformanceStrategy(),
    A: new APerformanceStrategy(),
    B: new BPerformanceStrategy(),
  };

  const strategy = strategies[performanceLevel];
  if (strategy) {
    return strategy.calculate(salary);
  }

  return 0; // 默认情况
};

console.log(calculateBonus('S', 1000)); // 输出: 4000
console.log(calculateBonus('A', 1000)); // 输出: 3000
console.log(calculateBonus('B', 1000)); // 输出: 2000


但是在js中,不一定是要用这种class形式写,才叫策略模式。这种模式 在后端语言中比如java 可能会经常用到,但是在js中,往往有更为明了的策略模式写法。把策略类弄成对象的形式,因为在js中,function 也是 Object 对象类型。

var strategies = {
  S: function (salary) {
    return salary * 4;
  },
  A: function (salary) {
    return salary * 3;
  },
  B: function (salary) {
    return salary * 2;
  },
};

var calculateBonus = function (performanceLevel, salary) {
  var strategy = strategies[performanceLevel];
  if (strategy) {
    return strategy(salary);
  }
  return 0; // 默认情况
};

console.log(calculateBonus('S', 1000)); // 输出: 4000
console.log(calculateBonus('A', 1000)); // 输出: 3000
console.log(calculateBonus('B', 1000)); // 输出: 2000

使用函数的方式可以更简洁地定义策略,并且不需要使用类和继承的概念。

声明:BenBonBen博客|版权所有,违者必究|如未注明,均为原创

转载:转载请注明原文链接 - js 策略模式深入理解


过去太迟,未来太远,当下最好