JavaScript设计模式:策略模式

207 阅读2分钟

将不变的部分和变化的部分隔开是每个设计的主题

策略模式的定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。

策略模式至少由两个部分组成。第一部分是一组策略类,策略类封装了具体的算法,并负责具体的计算过程。第二个部分是环境类context,context接受客户的请求,随后把请求委托给某一个策略类。

使用场景:根据员工绩效和工资基数发放年终奖,例如:绩效s的人年终有四倍工资,绩效a的人三倍,绩效b的人两倍

策略类:

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 Bouns = function(){
	this.salary = null; //原始工资
	this.strategy = null; //绩效等级对应的策略对象
}
Bouns.prototype.setSalary = function(salary){
	this.salary = salary //设置员工的原始工资
}
Bouns.prototype.setStrategy = function(strategy){
	this.strategy = strategy //设置员工绩效等级对应的策略对象
}
Bouns.prototype.getBouns=function(){
	if(!this.strategy){
		throw new Error('未设置startegy属性')
	}
	return this.strategy.calculate(this.salary)
    //把计算奖金的操作委托给对应的策略对象
}

使用

var bonus = new Bouns();
bonus.setSalary(1000); 
bonus.setStrategy(new performanceS()); //设置策略对象
console.log(bonus.getBouns()) //输出:4000
bonus.setStrategy(new performanceA()); //设置策略对象
console.log(bonus.getBouns()) //输出:3000

javascript改造以后

var strategies = {
	'S':function(salary){
		return salary*4
	},
	'A':function(salary){
		return salary*3
	},
	'B':function(salary){
		return salary*2
	}
}
var calculateBouns = function(level,salary){
	return strategies[level](salary)
}
console.log(calculateBouns('S',2000))//输出:8000
console.log(calculateBouns('A',1000))//输出:3000

策略模式优缺点:

1.策略模式利用组合、委托、和多态等技术和思想,可以有效的避免多重条件选择语句。

2.策略模式提供了对外开放-封闭原则的完美支持,将算法封装在独立的strategy中,使它们易于切换,理解和扩张。

3.策略模式的算法也可以复用在系统的其他地方,从而避免许多重复的复制黏贴工作。

4.策略模式中利用组合和委托让context拥有执行算法的能力,这也是继承的一种更轻便的替代方案。

缺点:策略模式会在程序中增加很多策略类或者策略对象。但是比把逻辑放在context中要好。

注意:使用策略模式,必须了解所有的ctrategy(策略)必须了解各个strategy之间的不同点,这样才能选择一个合适的strategy。比如要选择合适的旅游路线,必须先了解选择飞机,火车,自行车等方案的细节。此时strategy要向客户暴露他的所有实现,这是违反最少知识原则的。