深入理解JavaScript系列(33):设计模式之策略模式详解
介绍
策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户。
正文
在理解策略模式之前,我们先来一个例子,一般情况下,如果我们要做数据合法性验证,很多时候都是按照swith语句来判断,但是这就带来几个问题,首先如果增加需求的话,我们还要再次修改这段代码以增加逻辑,而且在进行单元测试的时候也会越来越复杂,代码如下:
validator={ validate:function(value,type){ switch(type){ case'isNonEmpty': { returntrue;//NonEmpty验证结果 } case'isNumber': { returntrue;//Number验证结果 break; } case'isAlphaNum': { returntrue;//AlphaNum验证结果 } default: { returntrue; } } } }; // 测试 alert(validator.validate("123","isNonEmpty"));
那如何来避免上述代码中的问题呢,根据策略模式,我们可以将相同的工作代码单独封装成不同的类,然后通过统一的策略处理类来处理,OK,我们先来定义策略处理类,代码如下:
varvalidator={
//所有可以的验证规则处理类存放的地方,后面会单独定义 types:{},
//验证类型所对应的错误消息 messages:[],
//当然需要使用的验证类型 config:{},
//暴露的公开验证方法 //传入的参数是key=>value对 validate:function(data){
vari,msg,type,checker,result_ok;
//清空所有的错误信息 this.messages=[];
for(iindata){ if(data.hasOwnProperty(i)){
type=this.config[i]; //根据key查询是否有存在的验证规则 checker=this.types[type];//获取验证规则的验证类
if(!type){ continue;//如果验证规则不存在,则不处理 } if(!checker){//如果验证规则类不存在,抛出异常 throw{ name:"ValidationError", message:"Nohandlertovalidatetype"+type }; }
result_ok=checker.validate(data[i]);//使用查到到的单个验证类进行验证 if(!result_ok){ msg="Invalidvaluefor*"+i+"*,"+checker.instructions; this.messages.push(msg); } } } returnthis.hasErrors(); },
//helper hasErrors:function(){ returnthis.messages.length!==0; } };