狠狠的学 -- 策略模式

85 阅读2分钟

  达到同一个目的可以用多种方法,在不同的情况下可以切换不同的方法达到同样的效果。策略模式关键在于将不同的算法处理过程封装起来,在不同情况下可以切换使用不同的算法,而不是直接将算法的实现逻辑写在不同分支语句内。

  算法的实现和使用其实是两个职责,如果都写在if...else结构语句内无疑违反了RSP,同样违反了开闭原则。

  这样做可以减少大量if...else/switch语句,使代码更易维护、扩展。然而多了策略对象,在使用前得了解所有的策略,选择合适的策略。

  封装算法的目的是解耦算法处理过程与调用者的关系,将算法的实现和使用区分开。分析大量if...else语句,从两个职责来看,可以增加中间对象来解耦算法的实现和调用,转变为 3 个实体之间的关系(调用者、中间对象、实际的算法处理过程)。

  传统面向对象语言将算法封装在类中,通过类将请求委托给具体的策略对象。而JavaScript中可以使用对象函数来封装算法。策略模式在JS中是浑然天成的(主要体现在一等函数对象的函数式特性上,用高阶函数封装算法与行为,并且可以传递函数)。

// 计算奖金 - if...else
var calculateBonusIE = function(level, salary) {
    if (level === "S") {
        return salary * 4;
    }

    if (level === "A") {
        return salary * 3;
    }

    if (level === "B") {
        return salary * 2;
    }
}
console.log(calculateBonusIE('S', 4000));
console.log(calculateBonusIE('A', 4000));
console.log('-------------------------');
// 计算奖金 - 策略模式版本
var strategies = {
    "S": function (salary) {
        return salary * 4;
    },
    "A": function (salary) {
        return salary * 3;
    },
    "B": function (salary) {
        return salary * 2;
    }
}
function calculateBonus(level, salary) {
    return strategies[level](salary);
}
console.log(calculateBonus('S', 4000));
console.log(calculateBonus('A', 4000));