在《javascript设计模式》中,作者并没有向我们介绍策略模式,然而它却是一种在开发中十分常见的设计模式。最常见的就是当我们遇到一个复杂的表单验证的时候,常常需要编写一大段的if和else逻辑代码,这些代码维护起来非常麻烦,但是麻烦的事情远远不止于此。通常一个项目中不止涉及单个的表单或者数据的认证,他们往往成群结队地出现。所以一开始为了他们而编写的if和else逻辑代码不仅会显得非常臃肿,而且随着项目的扩展,使你的代码或变得越来越黏糊,就像。。。。。。。是的,就像意大利面条一样!为了改动小小的一个逻辑——姓名从以前的三个字的限制变成现在四个字限制——,为了这个,你必须把整个项目的所有关于验证的界面都查找替换个遍。但是如果你一开始采用合理的设计模式来设计你的代码的话,或许结果就并不是在漆黑的夜苦苦地加班了。在这里,我们以一个简简单单的数据类型为例,来了解一下我们的策略模式是怎么样帮助我们工作的。

var data = {
firstName : '晓薇儿',
lastName : '被瑞尔',
age : 100,
sex : 0,
adress : 'stree 12th',
phone : '15988563324',
boss : true
}

这是我们要验证的数据源,我们限制条件如下

1.fistName和lastName字段不能为空并且长度小于三;

2.age字段不能大于100,

3.电话号码必须是正确的

4.地址长度必须限制在200个字符以内

5.是不是老板这个嘛,只能告诉我们是true和false,也就是只能是boolean类型

来看看传统的验证做法:

function g() {
if(data.firstName!="" && data.length < 4) {
return false;
}
if(data.lastName !="" && data.length <4) {
return false;
}
......................//此处省略N多行
}

这还只是一个数据源的验证代码,随着数据源的增加,代码会不会庞大起来?

下面让我们来看看策略模式是怎么样实现的

	var voidValue = {//策略者
C : {},//默认配置规则
M : {//未通过验证时输出的信息
isEmpty : 'EMPTY',
isPhone : 'NOTPHONE',
isBoolean : 'NOTBOOLEAN',
isLength : 'BIGGER THAN MAX',
isUndefined : 'UNDEFINED',
isNumber : 'NOTNUMBER'
},
R : {//自定义规则,所有的规则在里面逐步添加
isEmpty : function(v) {
return v != '';
},
isUndefined : function(v) {
return typeof v === 'undefined';
},
isPhone : function(v) {
return /^1[3|4|5|8]\d{9}$/.test(v);
},
isBoolean : function(v) {
return Object.prototype.toString.call(v) === '[object Boolean]';
},
isNumber : function(v) {
return Object.prototype.toString.call(v) === '[object Number]';
},
isName : function(v) {
return /^[\u4E00-\u9FFF]{1,6}$/.test(v);
},
                    isAdress : function(v) {
                        return this.isEmpty(v) && v.length<200;
                    }
},
vaild : function(d) {//入口函数,传入数据源
for(var i in d) {//循环传入的对象
if(!this.C[i]) continue;
if(this.C[i].fn) {//判断是否有用户自定义输出的字符串,这里其实是经常用到的,比如某个字段没有通过验证需要怎么样提示,以及提示的文字,在验证表单是尤其重要!
var fn = this.R[this.C[i]['fn']] || this.C[i]['fn'], message = this.C[i]['tip'];
}else {
var fn = this.R[this.C[i]] || this.C[i], message = this.M[this.C[i]];
}
var t = Object.prototype.toString.call(fn);//这里我们判断是需要执行验证函数还是比对数值大小
if(t === '[object Function]') {
if(!fn(d[i])) {
console.warn(message);
return false;
}
}else if(t === '[object Number]') {
if(!/\d+/.test(d[i]) || parseInt(d[i]) >= fn) {
console.warn(message);
return false;
}
}
}
return d;//如果都匹配到了,可以输出完整的数据源对象。
}
}

  我们来看下他如何调用的

voidValue.C = {//C是公开的对象,外面可以任意改变其值,是为了针对多种多样的验证逻辑。
firstName : {fn : 'isName', tip : '请填写正确的姓名'},//最外层的字段必须是和数据源字段一一对应的,里面的对象第一个参数fn是需要验证的方法,第二个是未通过该方法时提示的文字。
lastName : {fn : 'isName', tip : '请填写正确的姓名'},
age : {fn : 122, tip : '您是彭祖吗?这么高龄!'},
     adress : {fn : 'isAdress', tip : '请输入正确的地址'},
phone : {fn : 'isPhone', tip : '请填写正确的手机号码'},
boss : {fn : 'isBoolean', tip : '你确定你是老板妈妈吗?'},
}

首先你要做的是改变这个策略者的验证逻辑,如果之后的某个字段验证逻辑一样的话,就不必再写一次了。下面就是简简单单有一句调用入口函数

var m = voidValue.vaild(data);

如果一切都顺利,就会放回data给m了。如果不顺利,也就是说某个字段未通过验证,那么m === false;

javascript 设计模式-----策略模式的更多相关文章

  1. javascript设计模式——策略模式

    前面的话 在程序设计中,常常遇到类似的情况,要实现某一个功能有多种方案可以选择.比如一个压缩文件的程序,既可以选择zip算法,也可以选择gzip算法.这些算法灵活多样,而且可以随意互相替换.这种解决方 ...

  2. javascript设计模式-策略模式

    策略模式笔记   将定义的一组算法封装起来,使其相互之间可以替换.   封装的算法具有一定独立性,不会随客户端变化而变化.   与状态模式异同?     1. 结构上看,它与状态模式很像,也是在内部封 ...

  3. JavaScript设计模式 - 策略模式(表单验证)

    表单提交的时候,总是要校验,不同的表单可能校验相同的功能. 为了避免代码重复的复制黏贴,使用策略模式,写出来的代码赏心悦目,且可扩展,还可以作为插件到处使用 <!DOCTYPE html> ...

  4. JavaScript实现策略模式

    在开篇之前先分享今天看到的一句关于设计模式的话:将不变的部分和变化的部分隔开是每个设计模式的主题 请大家自行感受这句话的精髓所在,并且思考学习设计模式究竟能给我们编程带来什么样的东西,欢迎大家在文章下 ...

  5. JS设计模式——策略模式

    设计模式高大上,业务代码用不上...平时用不上我们就可以忽略了吗? 非也,就像面试造火箭,工作拧螺丝一样.万一我们公司哪天要造火箭了,你得立马能上手. 同时,有些复杂的业务代码也可以用设计模式的思想去 ...

  6. 15. 星际争霸之php设计模式--策略模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  7. [.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型)

    [.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它 ...

  8. linkin大话设计模式--策略模式

    linkin大话设计模式--策略模式 Strategy [ˈstrætədʒi]  策略 策略模式用于封装系列的算法,这些算法通常被封装在一个称为Context的类中,客户端程序可以自由的选择任何一种 ...

  9. [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型)

    [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模 ...

随机推荐

  1. JavaScript 常用函数总结

    javascript函数:  ·常规函数  ·数组函数  ·日期函数  ·数学函数  ·字符串函数 .cookie函数 1.常规函数 javascript常规函数包括以下9个函数:  (1)alert ...

  2. java实现调用ORACLE中的游标和包

    今天把oracle中的包和游标学习了下,不废话,网上的的有些代码是错误的,抄来抄去,就自己实践了下,做个记录.直接上图,上代码 通过plsql创建自己的的包,包分为包头和包体. 1.包头如下: CRE ...

  3. IplImage 结构解读

    IplImage 结构解读: typedef struct _IplImage { int nSize;                              /* IplImage大小,等于wi ...

  4. GDI+ 发生一般性错误解决办法

    错误的代码g对象继续占用 未释放资源 如果路径不一样 没问题 相同路径 获取图片进行 缩略会造成GDI错误 /// <summary> /// 生成缩略图 /// </summary ...

  5. MariaDB kill命令

    MariaDB的KILL命令不只可以杀掉连接,而且可以只杀掉某连接当前的SQL,而不断开连接.KILL QUERY thread_id;kill thread_id可以杀掉当前的连接,而kill QU ...

  6. VS与ultraedit 正则表达式替换

    ASP中把request("{param}")调用替换为requestX("{param}") VS 表达式替换(?<a>request\(&quo ...

  7. as画柱型图的简单算法(关于柱型图宽和间距问题)

    做统计数据,经常用到如下柱型图: 柱图的X轴宽度(W)是已知的,在不影响柱的美观度情况下,怎么确定柱的宽度(w1)和柱间距(p1)的具体数值或比例呢? 在X轴宽度(W)已确定,柱的个数(A)是个不定值 ...

  8. 使用jigdo下载debian [windows环境下]

    使用jigdo下载debian  本文地址:http://www.cnblogs.com/yhLinux/p/4104451.html 准备工作: 下载jigdo:http://atterer.org ...

  9. C程序员学bash shell容易掉坑的注意点(未完待续)

    shell解释器很娇气,有一点点不合乎规范的编码风格都会让脚本歇菜. 1. 空格该有还是该没有要看情况.该有的时候不能没有!该没有的时候不能有! 变量赋值的等号两边不能有空格. 2. 在shell中是 ...

  10. 算法入门笔记------------Day4

    1.WERTYU 输入一个错位后敲出的字符串,输出打字员本来想打出的字 #include<stdio.h> char *s="`1234567890-=QWERTYUIOP[]\ ...