JavaScript设计模式之策略模式

策略模式

定义

  指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。

组成

一个基于策略模式的程序有以下组成部分:

  • 抽象策略角色: 通常由一个接口或者抽象类实现
  • 具体策略角色:包装了相关的算法和行为
  • 环境角色:持有一个策略类的引用,最终给客户端调用

应用场景

  • 针对同一类型问题的多种处理方式,在运行时动态选择具体要执行的行为
  • 在不同情况下需要使用不同的策略(算法),或者在未来还可能新增其它方式来实现
  • 隐藏具体策略(算法)的实现细节,彼此完全独立

代码实现

1 .使用面向对象的思想实现策略模式:

// 定义抽象策略角色
var Calculator = function(num1, num2){
	this.num1 = num1;
	this.num2 = num2;
};
Calculator.prototype.caculate = function() {};

// 定义具体策略角色(加法)
var Add = function(num1, num2){
	Calculator.call(this, num1, num2);
};
inheritPrototype(Add, Calculator);		// 寄生组合式继承
Add.prototype.caculate = function() {
	console.log("num1 + num2 = " + (this.num1 + this.num2));
};
// 定义具体策略角色(减法)
var Sub = function(num1, num2){
	Calculator.call(this, num1, num2);
};
inheritPrototype(Sub, Calculator);
Sub.prototype.caculate = function() {
	console.log("num1 - num2 = " + (this.num1 - this.num2));
};
// 定义具体策略角色(乘法)
var Mul = function(num1, num2){
	Calculator.call(this, num1, num2);
};
inheritPrototype(Mul, Calculator);
Mul.prototype.caculate = function() {
	console.log("num1 * num2 = " + (this.num1 * this.num2));
};
// 定义具体策略角色(除法)
var Div = function(num1, num2){
	Calculator.call(this, num1, num2);
};
inheritPrototype(Div, Calculator);
Div.prototype.caculate = function() {
	console.log("num1 / num2 = " + (this.num1 / this.num2));
};
// 定义环境角色,负责和具体的策略交互,持有一个策略类的引用
var Environment = function(strategy) {
	this.strategy = strategy;
}
Environment.prototype.caculateRes = function(){
	return this.strategy.caculate();
}

var addMethod = new Environment(new Add(10, 5));
var subMethod = new Environment(new Sub(10, 5));
var mulMethod = new Environment(new Mul(10, 5));
var divMethod = new Environment(new Div(10, 5));
addMethod.caculateRes()				// 打印结果 15
subMethod.caculateRes()				// 打印结果 5
mulMethod.caculateRes()				// 打印结果 50
divMethod.caculateRes()				// 打印结果 2

如果需要增加新的计算方法,只需增加具体的策略实现即可,具有良好的扩展性。

2.使用Javascript版本的策略模式

// 策略对象
var calculate = function() {
	// 内部实现算法
	var strategy = {
		add: function(num1, num2){
			return num1 + num2;
		},
		sub: function(num1, num2) {
			return num1 - num2;
		},
		mul: function(num1, num2) {
			return num1 * num2;
		},
		div: function(num1, num2) {
			return num1 / num2;
		}
	}
	// 策略算法调用
	return {
		calculateRes: function(type, value) {
			return strategy[type] ? strategy[type](...value) : "计算方法不存在"
		},
	}
}();

console.log("num1 + num2 = " + calculate.calculateRes('add', [10,5]))   // 15
console.log("num1 - num2 = " + calculate.calculateRes('sub', [10,5]))	// 5
console.log("num1 * num2 = " + calculate.calculateRes('mul', [10,5]))	// 20
console.log("num1 / num2 = " + calculate.calculateRes('div', [10,5]))	// 2

需要增加计算方式,只需在 strategy 增加对应的算法即可。

总结

  策略模式最主要的特色就是创建了一系列策略算法,每组算法处理的业务都是相同的,只是处理过程或者处理结果不一样,所以它们又是可以相互替换的。这解决了算法和使用者之间的耦合。在测试层面上,由于每组算法是相互独立的,该模式更方便我们对每组算法执行单元测试,以保证算法的质量。

你可能感兴趣的:(JavaScript)