Appearance
js 和 java 不同作为弱类型语言,在使用策略模式上也整体思路是一样的,但是代码编写上略有不同
举个例子公司要发奖金,根据不同等级奖金比例也是不同,为了判断每一个人应该根据等级和等级所对应的倍数得到的奖金,写出下面的代码
js
var calculateBonus = function (performanceLevel, salary) {
if(performanceLevel === 's'){
return salary * 4
}
if(performanceLevel === 'a'){
return salary * 4
}
if(performanceLevel === 'b'){
return salary * 4
}
}
calculateBonus('s',2000)
calculateBonus('a',600)
先按照js 函数式编程的思路去来做,只创建函数不创建类
js
var performanceS = function( salary ){
return salary * 4;
};
var performanceA = function( salary ){
return salary * 3;
};
var performanceB = function( salary ){
return salary * 2;
};
var calculateBonus = function( performanceLevel, salary ){
if ( performanceLevel === 'S' ){
return performanceS( salary );
}
if ( performanceLevel === 'A' ){
return performanceA( salary );
}
if ( performanceLevel === 'B' ){
return performanceB( salary );
}
};
calculateBonus( 'A' , 10000 ); // 输出:30000
按照之前学过的策略模式 js 没有接口的概念 但是也先确定一下每个策略 统一使用调用的方法叫做calculate
js
// 算法
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;
};
//接下来定义奖金类Bonus:
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
js 天然特性的策略模式
但实际上 js 是可以直接天然使用策略模式
js
var strategies = {
"S": function( salary ){
return salary * 4;
},
"A": function( salary ){
return salary * 3;
},
"B": function( salary ){
return salary * 2;
}
};
var calculateBonus = function( level, salary ){
return strategies[ level ]( salary );
};
console.log( calculateBonus( 'S', 20000 ) ); // 输出:80000
console.log( calculateBonus( 'A', 10000 ) ); // 输出:30000
js 函数编程策略模式
函数作为一等对象的概念。在某些编程语言中,函数可以像其他数据类型(如整数、字符串等)一样被当作值来使用。这意味着函数可以作为参数传递给其他函数,可以作为函数的返回值,可以存储在变量中,并且可以在运行时动态地创建和修改。这种能力使得函数可以更灵活地用于编程任务。
策略模式是一种设计模式,用于在运行时选择算法或行为。它允许在不修改现有代码的情况下定义一系列算法,并根据需要在运行时选择其中之一。这种模式通常通过将算法封装在独立的类中,并使用接口或抽象类定义它们之间的共同行为来实现。
Peter Norvig在他的演讲中指出,当使用支持函数作为一等对象的编程语言时,策略模式可以更为简洁和隐式地实现。这是因为函数作为一等对象的特性使得我们可以直接将不同的策略(即不同的函数)作为参数传递给其他函数,从而实现动态的算法选择。这种方式避免了显式地定义和实现多个类来表示不同的策略,从而简化了代码结构和维护。
因此,Peter Norvig的这句话强调了在支持函数作为一等对象的编程语言中,策略模式可以更加自然和隐式地实现,从而提供更高的灵活性和简洁性。
js
var S = function( salary ){
return salary * 4;
};
var A = function( salary ){
return salary * 3;
};
var B = function( salary ){
return salary * 2;
};
var calculateBonus = function( func, salary ){
return func( salary );
};
calculateBonus( S, 10000 ); // 输出:40000
总结
相比java的策略模式需要建立接口建立类来维护,js天然优势就是函数是一等公民,我们可以不用像java那么复杂来实现策略