JavaScript形而上的策略模式
阿新 • • 發佈:2018-08-07
定義 table ava 使用 amd 簡潔 prop 相互 並且 設置了不同的參數,導致同樣的
所以策略模式是指,定義一系列的算法,把它們一個個封裝起來, 並且使它們可相互替換。
什麽是策略模式?
先看代碼片段1。
// 代碼片段1
var bonus = new Bonus();
bonus.setSalary(10000);
bonus.setStrategy(new performanceS());
console.log('bounsS' ,bonus.getBonus());
// => 40000
bonus.setStrategy(new performanceA());
console.log('bounsA',bonus.getBonus());
// => 30000
bonus
是一個對象,而對象自帶上下文。
這個對象在運行的不同階段,通過setStrategy
bonus.getBonus()
輸出結果不同。所以策略模式是指,定義一系列的算法,把它們一個個封裝起來, 並且使它們可相互替換。
下面的代碼片段2是代碼片段1的定義。
// 代碼片段2 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); };
改進的策略模式
同樣的bonus.getBonus()
,卻輸出結果不同。
當業務變得復雜,這會導致代碼難以預測。
我們稍微改進一下,讓對象初始化時接收一個策略對象,並且設置策略屬性不可修改。
// 代碼片段3 var bonusFactory = function(strategy){ this.salary = null; Object.defineProperty(this, 'strategy',{ value: strategy, writable: false, configurable:false, }) }; bonusFactory.prototype.setSalary = function (salary) { this.salary = salary; }; bonusFactory.prototype.getBonus = function () { return this.strategy.calculate(this.salary); }; var bonusS = new bonusFactory(new performanceS()); bonusS.setSalary(10000); bonusS.strategy = 11; console.log('bonusS', bonusS.getBonus()); var bonusA = new bonusFactory(new performanceA()); bonusA.setSalary(10000); console.log('bonusA', bonusA.getBonus());
策略模式的函數式寫法
這裏使用了名為ramda
的函數式工具庫。
var R = require('ramda');
var salaryS = function(salary) {
return salary * 4;
};
var salaryA = function(salary) {
return salary * 3;
};
var salaryB = function(salary) {
return salary * 2;
};
var getBonus = function(salary, strategy){
return strategy(salary);
};
var getBonusFacotry = R.curry(getBonus);
var getBonusS = getBonusFacotry(R.__, salaryS);
var getBonusA = getBonusFacotry(R.__, salaryA);
var getBonusB = getBonusFacotry(R.__, salaryB);
var getBouns1000 = getBonusFacotry(1000, R.__);
console.log('封裝獎金計算方式的策略');
console.log(getBonusS(1000));
console.log(getBonusA(1000));
console.log(getBonusB(1000));
console.log('封裝獎金數目的策略');
console.log(getBouns1000(salaryS));
console.log(getBouns1000(salaryA));
console.log(getBouns1000(salaryB));
可以看到函數式寫法更加靈活和簡潔。
JavaScript形而上的策略模式