对Javascript系列(33)的深刻理解:设计模式策略模式的详细解决方案
策略模式定义算法家族并封装它们,以便它们彼此替换。这种模式使得算法的变化不影响算法的用户。
文本
在我们理解的策略,第一个例子,在正常情况下,如果我们想做数据验证,很多都与开关语句判断的依据,但它会带来一些问题,首先,如果需求增加,我们又想修改代码,增加逻辑,当单元测试将变得越来越复杂,代码如下:
复制代码代码如下所示:
验证= { {
验证:函数(值,类型){
开关(类型){
case'isnonempty:
{
返回true; / /非空验证结果
}
case'isnumber:
{
返回true;数字验证结果
打破;
}
case'isalphanum:
{
返回true; / /字母数字验证结果
}
违约:
{
返回true;
}
}
}
};
测试
警报(validator.validate(123
如何避免上述代码中出现的问题根据策略模式,我们可以将相同的工作代码独立地分为不同的类,然后通过统一的策略处理类处理它们。好的,我们首先定义策略处理类。代码如下:
复制代码代码如下所示:
VaR验证= { {
所有的验证规则都位于单独定义后面
类型:{ },
对应于验证错误消息的类型。
消息:{ },
当然,需要使用类型验证
配置:{ },
公开曝光/验证方法
参数
验证:函数(数据){
var i,味精,类型检查器,result_ok;
清空所有错误消息
this.messages = { };
对于(i在数据中){
如果(data.hasownproperty(I)){
根据检查验证规则是否存在
检查器=这个类型。
如果(!型){
继续;如果验证规则不存在,则不进行处理。
}
(如果!检查器)如果验证规则类不存在,则抛出异常。
把{
名称:个
消息:没有验证类型+类型
};
}
result_ok = checker.validate(数据{我}); / /使用检查核实个人验证类
如果(!result_ok){
味精=无效值为*+我+*+ checker.instructions;
This.messages.push(MSG);
}
}
}
返回this.haserrors();
},
赫尔珀
haserrors:函数(){
返回this.messages.length = = 0;
}
};
接下来的工作是定义存储在类型中的所有验证类,我们只给出几个示例。
复制代码代码如下所示:
验证给定值是否为空。
validator.types.isnonempty = { {
验证:函数(值){
返回值;
},
说明:传入值不能为空
};
验证给定值是否为
validator.types.isnumber = { {
验证:函数(值){
返回!IsNaN(值);
},
说明:传入的值只能是合法数字,例如:1、3.14或2010 。
};
验证给定值是否只有字母或数字。
validator.types.isalphanum = { {
验证:函数(值){
返回!a-z0-9 } { ^ / / i.test(价值);
},
说明:传入的值只能保护字母和数字,并且不包含特殊字符。
};
在使用它时,我们首先定义需要验证的数据集,然后我们需要定义每个数据需要验证的规则类型。代码如下:
复制代码代码如下所示:
var数据{ {
first_name:汤姆
last_name:徐
年龄:未知
用户名:tomxu
};
validator.config = { {
first_name:'isnonempty,
年龄:'isnumber,
用户名:'isalphanum
};
最后,获得验证结果的代码很简单:
复制代码代码如下所示:
validator.validate(数据);
如果(validator.haserrors()){
console.log(validator.messages.join());
}
总结
策略模式定义了一系列算法。从概念上讲,所有这些算法都在做同样的事情,但只实现不同的方式。它们可以以相同的方式调用所有方法,并减少算法类和算法类之间的耦合。
在另一个层次上,单元测试也很方便地单独定义算法类,因为它们可以通过自己的算法逐个测试。
在实际应用中,不仅可以封装算法,而且可以封装几乎任何类型的规则,因此在分析过程中需要不同的业务规则应用,因此我们可以考虑采用策略模式来处理各种变化。