Javascript设计模式之策略模式

158 阅读2分钟

前言:菜鸡也有梦想,而我的梦想就是进一个真正的互联网大厂。以前学习的时候没有系统的整理,从今天开始要保持每周写博客的习惯,希望自己可以有所成长。为了培养编程思维,决定从设计模式开始写起。我是通过读《Javascript设计模式与开发实践》来学习设计模式,并且将知识点和收获记录在博客中。

此文仅记录本人阅读《JavaScript设计模式与开发实践》的知识点与想法,感谢作者曾探大大写出这么好的一本书。如有冒犯,请联系本人:markcoder@outlook.com处理,请大家购买正版书籍。

1.策略模式介绍

策略模式指的是定义一系列的算法,把它们一个个封装起来。将不变的部分和变化的部分隔开是每个设计模式的主题,策略模式也不例外,策略模式的目的就是将算法的使用与算法的实现分离开来。

2.代码示例

举一个实际的例子,根据绩效计算年终奖,绩效为S的人年终奖有4倍工资,绩效为A的人年终奖有3倍工资,而绩效为B的人年终奖有2倍工资。

我们可以编写一个名为calculateBonus的函数来计算每一个人的奖金。

function calculateBonus (performance, salary) {
    if (performance === 'S') {
        return salary * 4;
    }
    
    if (performance === 'A') {
        return salary * 3;
    }
    
    if (performance === 'B') {
        return salary * 2;
    }
}
calculateBonus('A', 6000); // 18000
calculateBonus('S', 6000); // 24000

我们可以发现,这段代码中包含了太多的if判断,需要覆盖所有的情况。而且代码缺乏弹性,如果多一种C绩效,就要在函数内部添加代码。所以我们要进行初步的优化。

我们将各种算法封装到不同的函数里面,用良好的命名对应不同的算法。

function performanceS (salary) {
    return salary * 4;
}

function performanceA (salary) {
    return salary * 3;
}

function performanceB (salary) {
    return salary * 2;
}

var calculateBonus = function (performance, salary) {
    if (performance === 'S') {
        return performanceS(salary);
    }
    
    if (performance === 'A') {
        return performanceA(salary);
    }
    
    if (performance === 'B') {
        return performanceB(salary);
    }
}

calculateBonus('S', 3000); // 12000

现在代码有了一定的改善,但是没有解决最重要的问题,calculateBonus有可能越来越庞大,而且在系统变化的时候缺乏弹性,所以我们用策略模式来重构代码。

var performanceS = function () {};
performanceS.prototype.calculate = function (salary) {
    return salary * 4;
};

var performaceA = function () {};
performaceA.prototype.calculate = function (salary) {
    return salary * 3;
};

var performaceB = function () {};
performaceB.prototype.calculate = function (salary) {
    return salary * 2;
};

var Bonus = function () {
    this.salary = null;
    this.strategy = null;
};
Bonus.prototype.setSalary = function (salary) {
    this.salary = salary;
};
Bonus.prototype.setStrategy = function (strategy) {
    this.strategy = strategy;
};
Bonus.prototype.getBonus = function () {
    return this.strategy.calculate(this.salary);
};

var bonus = new Bonus();
bonus.setSalary(1000);
bonus.setStrategy(new performaceB());
bonus.getBonus(); // 2000

3.Javascript策略模式

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

var calculate = function (level, salary) {
    return strategies[level](salary);
};

calculate('S', 2000); // 8000
calculate('A', 2000); // 6000

参考

《JavaScript设计模式与开发实践》—— 曾探