策略模式
定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换(算法被封装在一个策略类的内部方法里,在用户对环境类请求时,环境类将请求交给对应的策略对象去计算)
在策略模式中,创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
假设现在有个游戏在卖武器。武器分为多个级别,比如青铜,黑铁,白银,黄金等
假设你接手了这个游戏的武器售卖业务,现在要开发一个售卖系统,其中一个功能就是根据武器底价和武器级别计算价格 于是你写下了如下代码
var weaponSell = function(base_price, weapon_power) {
if(weapon_power == "青铜") return base_price * 2
else if(weapon_power == "黑铁") return base_price * 4
else if(weapon_power == "白银") return base_price * 6
else if(weapon_power == "黄金") return base_price * 10
}
显然上面的代码如果还有其他武器级别,或者需要更改某个武器级别的基本价格的倍数又或者想要添加一个武器级别,我们都需要去这个函数的内部更改。这违背了开放闭合原则(对扩展功能开放,对修改原来代码达到新功能的目的关闭)
复用性差。如果需要用到其中的某个计算价格的算法,只能复制粘贴
于是我们可以将各种算法封装到一个小函数里面如下面
function QingTong(base_price) {
return base_price * 2
}
function HeiTie(base_price) {
return base_price * 4
}
function BaiYin(base_price) {
return base_price * 6
}
function HuangJin(base_price) {
return base_price * 10
}
于是原有代码变成了
var weaponSell = function(base_price, weapon_power) {
if(weapon_power == "青铜") QingTong()
else if(weapon_power == "黑铁") HeiTie()
else if(weapon_power == "白银") BaiYin()
else if(weapon_power == "黄金") Huangjin()
}
计算价格的算法得到了复用,但是最核心的问题还在,那就是判别武器的级别,依据(武器级别)策略对象去改变(weaponSell)context对象的行为
于是策略模式便可以用上了
策略模式的目的就是将算法的实现和使用分开。
策略模式的实现:
至少由两部分组成:策略类和环境类
策略类封装了具体的算法,它还负责具体的计算过程
环境类接收客户的请求,并委托给策略类去计算
```javascript
//策略类
var strategies = {
"QingTong": function(base_price) {return base_price * 2},
"HeiTie": function(base_price) {return base_price * 4},
"BaiYin": function(base_price) {return base_price * 6},
"HuangJin": function(base_price) {return base_price * 10},
}
//环境类接收一个武器级别参数和一个底价参数
var context = function(base_price, weapon_power) {
return this.strategies[weapon_power](base_price)
}
context(10, "QingTong") // 20