1. 介绍

策略模式是JS设计模式中一大重要的模式有着广泛的应用

2. 定义

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

3. 应用

根据等级、工资计算奖金等类似情况、使用不同的动画效果、表单验证等

4. 思想

把算法实现和算法调用分开

5. 实现

1. 基本的策略模式

这个例子是根据传统的面向对象语言进行改造的,不同的类都实现了相同的方法,传入不同的实例都可以调用相同的方法。这其中用到了组合、委托、多态的思想。其中把不同的实现过程进行拆分,分成performanceS,performanceA,这是组合的思想,都实现相同的方法calculate这是多态的思想,多态的意思是不同的对象调用相同的方法其结果是不同的。再通过Bonus类去调用这是委托。

var performanceS=function(){}
performanceS.prototype.calculate=function(salary){
    return salary*4
}
var performanceA=function(){}
performanceA.prototype.calculate=function(salary){
    return salary*3
}
var Bonus=function(){
    this.salary=""
    this.strategy=""
}
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(1000)
bonus.setStrategy(new performanceS())
console.log(bonus.getBonus())//4000
bonus.setStrategy(new performanceA())
console.log(bonus.getBonus())//3000

2. JS版本策略模式

在上个例子中虽然初步实现了策略模式,但是是仿照的传统面向对象语言,而JS的实现更为简单,直接把原来的strategy实例定义成函数,原先的Bonus类用calculateBonus函数来委托。组合的思想也还是比较明显,多态在这里体现得不是很明显,在strategieslevel这句中体现。

var strategies={
    S:function(salary){
        return salary*4
    },
    A:function(salary){
        return salary*3
    }
}
calculateBonus=function(level,salary){
    return strategies[level](salary)
}
console.log(calculateBonus('S',1000))//4000

3. 表单验证例子

在实际项目中经常需要对表单进行验证,用策略模式去实现表单验证是一种很不错的方法

var stratiges={
    isNotEmpty:function(val,errormsg){
        if(val.length<0){
            return errormsg
        }
    },
    minLen:function(val,minlen,errormsg){
        if(val.length<minlen){
            return errormsg
        }
    }
}
var Validate=function(){
    this.cache=[]
}
Validate.prototype.add=function(value,rules){
    for(var i=0,len=rules.length;i<len;i++){
        var rule=rules[i]
        var self=this;
        (function(rule){
            var arr = rule.strategy.split(":")
            var strategy=arr.shift()
            arr.unshift(value)
            arr.push(rule.errormsg)
            self.cache.push(function(){
                return stratiges[strategy].apply(null,arr)
            })
        })(rule)
        
    }
}
Validate.prototype.start=function(){
    for(var i=0,len=this.cache.length;i<len;i++){
        var errorMsg = this.cache[i]()
        if(errorMsg){
            return errorMsg
        }
    }
}
var validate = new Validate()
validate.add("yyyy",[{strategy:"isNotEmpty",errormsg:"不能为空"},{strategy:"minLen:7",errormsg:"不能少于7位"}])
var errormsg = validate.start()
console.log(errormsg)

LJun
60 声望2 粉丝