在《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. 深入浅出: Java回调机制(异步)

    一.什么是回调 回调,回调.要先有调用,才有调用者和被调用者之间的回调.所以在百度百科中是这样的: 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用.回调和异步调用. 回调 ...

  2. Select语句也会引起死锁

    项目上线,准备验收前出现了一个严重的问题:很多select语句作为死锁的牺牲,大部分报表无法打开.这个问题影响范围很大所有的报表都无法访问,而我们的报表是放在电视上面轮播的,电视放在工厂里面,所以出现 ...

  3. mvc+mysql+EF

    网上有很多关于EF在联机情况下利用nuget管理器安装的案例,我就讲一下脱机状况吧! 一.建立一个文件夹,例如D:/Packages 放入安装EF和mysql需要的包:EntityFramework. ...

  4. 解决ORA-00824: cannot set sga_target due to existing

    今天Linux服务器机子重启了下,Oracle启动不起来,提示:解决ORA-00824: cannot set sga_target due to existing 看了很多解决方法,发现下面这个特别 ...

  5. Hibernate和jsp做数据库单表的增删改查

    虽然很基础,但是我转牛角尖了~~~~这是几个文件 1.最重要的.Java文件 package com.chinasofti.hibb.struts; import org.hibernate.Sess ...

  6. 爱上WPF,努力才会有希望!

    从WinForm转向WPF开发已经有两个多月了,通过不断深入地学习与运用,现在是越来越爱它了.它实在是太强大了.运用WPF,你不仅可以做Win界面,也可以很快转向Web开发,因为Silverlight ...

  7. java 8种基本数据类型的默认值及所占字节数

    通过一段代码来测试一下 8种基本数据类型的默认值 package dierge; public class Ceshi { int a; double b; boolean c; char d; fl ...

  8. leaflet创建简单地图

    一.leaflet介绍: 1.Leaflet 是一个为建设移动设备友好的互动地图,而开发的现代的.开源的 JavaScript 库.它是由 Vladimir Agafonkin 带领一个专业贡献者团队 ...

  9. css3 自定义动画(1)

    <style> /*@-webkit-keyframes 动画名称 {} 用时:-webkit-animation:时间 动画名称; */ /* @-webkit-keyframes mo ...

  10. How to create Web Deployment Package and install the package

    Create Web Deployment Package To configure settings on the Connection tab In the Publish method drop ...