javaScript设计模式之策略模式
定义一系列的算法,把他们一个个封装起来,并且使他们可以互相替换
使用策略模式计算奖金
我们就用计算奖金为栗子,比如说绩效S就是4倍奖金,A绩效3倍奖金,B绩效2倍奖金,我们来提供一段代码,来方便计算
最初的代码实现
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
可以发现,这段代码非常简单,但是有个缺点,calculateBonus
函数比较庞大,包含很多if-else
`calculateBonus
函数缺乏弹性,比如需要修改一个绩效级别的奖金,就要深入函数内部实现,这样微分开放-封闭原则
算法复用性差,如果其他地方需要复用,还需要复制粘贴
使用策略模式-传统面向对象
var performanceS = function () {}; performanceS.prototype.calculate = function (salary) { return salary * 4; }; var performanceA = function () {}; performanceA.prototype.calculate = function (salary) { return salary * 3; }; var performanceB = function () {}; performanceB.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(10000); bonus.setStrategy(new performanceS()); // 设置策略对象 console.log(bonus.getBonus()); // 输出:40000 bonus.setStrategy(new performanceA()); // 设置策略对象 console.log(bonus.getBonus()); // 输出:30000
使用策略模式-javascript版本
var strategies = { "S": function( salary ){ return salary * 4; }, "A": function( salary ){ return salary * 3; }, "B": function( salary ){ return salary * 2; } } //同样,Context 也没有必要必须用 Bonus 类来表示,我们依然用 calculateBonus 函数 当Context 来接受用户的请求 。经过改造,代码的结构变得更加简单 var calculateBonus = function( level, salary ){ return strategies[ level ]( salary ); }; console.log( calculateBonus( 'S', 20000 ) ); console.log( calculateBonus( 'A', 10000 ) );