Skip to content
快速预览

策略模式(中)--前端

✍️ w 🕒 2023-08-01 14:34:55(10 months ago) 🔗 G.设计模式

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那么复杂来实现策略

Released under the MIT License.