策略模式:

定义了一系列的算法,把他们封装起来,是它们之间可以互相替换,此模式不会影响到使用算法的客户。

回忆下jquery里的animate方法:

$( div ).animate( {"left: 200px"}, 1000, 'linear' );  //匀速运动
$( div ).animate( {"left: 200px"}, 1000, 'cubic' ); //三次方的缓动

这2句代码都是让div在1000ms内往右移动200个像素. linear(匀速)和cubic(三次方缓动)就是一种策略模式的封装。

一般用在检验表单输入的合法性,根据策略模式,先将相同的工作代码单独封装成不同的类,然后通过统一的策略类来处理,例如:

 var vidata = {
// 所有可以的验证规则处理类存放的地方,后面会单独定义
types: {}, // 验证类型所对应的错误消息
messages: [], // 当然需要使用的验证类型
config: {}, validate:function(data){ var i, msg, type, checker, result_ok; // 清空所有的错误信息
this.messages = [];
for (i in data) { if (data.hasOwnProperty(i)) { type = this.config[i]; // 根据key查询是否有存在的验证规则
checker = this.types[type]; // 获取验证规则的验证类 if (!type) {
continue; // 如果验证规则不存在,则不处理
}; if (!checker) { // 如果验证规则类不存在,抛出异常
throw {
name: "ValidationError",
message: "No handler to validate type " + type
};
}; result_ok = checker.validate(data[i]); // 使用查到到的单个验证类进行验证
//若果检验的结果通过,则messages中不添加任何消息,即checker.instructions
if (!result_ok) {
msg = "Invalid value for *" + i + "*, " + checker.instructions;
this.messages.push(msg);
};
};
};
return this.hasError();
}, hasError:function(){
//如果全部通过,则messages的length为0;
return this.messages.length !== 0;
} };

定义了相同的策略处理类之后,在定义具体的处理函数:

vidata.types.isString = {

  validate: function (value) {
return value !== "";
},
instructions: "传入的值不能为空";//返回的不通过时候的消息
}; vidata.types.isNum = { validate: function (value) {
return !isNaN(value);
},
instructions: "传入的值只能是合法的数字,例如:1, 3.14 or 2010"//返回的不通过时候的消息
};
定义了具体的处理函数之后,我们可以随意在这个类上面增加我们需要的验证函数,验证规则,以及错误时候的信息,这样使用它:
  //要验证的数据
var data = {
userName:"rrr",
password:"3333" };
//验中的证规则的配置,其中key值要和data中的key值保持一致性,value值要和所验证的函数方法保持命名一致性。
vidata.config = {
userName:"isString",
password:"isNum"
};

当我们需要增加新的规则是,只需要分别在data,vidata.config,vidata.types做如下的增加:

//新添加的验证方法

vidata.types.isEmail = {

  validate: function (value) {
return /\w+((-w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+/.test(value)
},
instructions: "传入的值必须是邮箱格式!"//返回的不通过时候的消息
};
//新增加的验证邮箱数据
var data = {
......
email:"wang@163.com"
}; //在配置信息中这样配置:
vidata.config = {
......
email:"isEmail"
};

使用:

vidata.validate(data);//执行
if(vidata.hasError()){
console.log(vidata.messages);//返回来的结果。
};

单独定义算法类,也方便单元测试,可通过自己的算法进行测试。

实践中,不仅可以封装算法,也可以用来封装几乎任何类型的规则,是要在分析过程中需要在不同时间应用不同的业务规则,就可以考虑是要策略模式来处理各种变化。

参考:《javascript模式》

汤姆大叔:http://www.cnblogs.com/TomXu/archive/2012/03/05/2358552.html

http://www.alloyteam.com/2012/10/commonly-javascript-design-patterns-strategy-mode/

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

  1. [转]js设计模式-策略模式

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

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

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

  3. js 设计模式——策略模式

    策略模式(Strategy) 定义:将定义的一组算法封装起来,使其相互之间可以替换.封装的算法具有一定的独立性,不会随客户端的变化而变化 废话不多说,先来个例子 // 例如要写一个计算两个数加减乘除的 ...

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

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

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

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

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

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

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

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

  8. JAVA 设计模式 策略模式

    用途 Title 它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. 策略模式是一种行为型模式. 结构

  9. 设计模式-策略模式(Strategy Model)

    1.概述     在开发过程中常常会遇到类似问题,实现一个功能的时候往往有多种算法/方法(策略),我们可以根据环境的不同来使用不同的算法或策略来实现这一功能.     如在人物比较排序的实现中,我们有 ...

随机推荐

  1. 【转】每一个程序员需要了解的10个Linux命令

    作为一个程序员,在软件开发职业生涯中或多或少会用到Linux系统,并且可能会使用Linux命令来检索需要的信息.本文将为各位开发者分享10个有用的Linux命令,希望对你会有所帮助. 以下就是今天我们 ...

  2. 步进控件——UIStepper

    步进控件,可用于替换传统用于输入值的文本框.步进控件提供了“+”和“-”两个按钮,用来改变stepper内部value的增加或减少,调用的事件是UIControlEventValueChanged.由 ...

  3. webstorm 激活码

    WebStorm 2016 最新版激活(activation code方式) 注册时,在打开的License Activation窗口中选择“activation code”,在输入框输入下面的注册码 ...

  4. sql语句的截取字符串下标是从1开始

    这里的指的sqliter数据库 substr函数 substr(date,1,10)

  5. Python collections.defaultdict() 与 dict的使用和区别

    看样子这个文档是难以看懂了.直接看示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import collections s = [('yellow', ...

  6. sql server mdf碎片级数据库修复,数据库碎片级提取

    sql server mdf碎片级数据库修复,数据库碎片级提取   大家都知道MDF数据库文件一般都比较大,在磁盘中往往被存放到不连续的逻辑簇中,久而久之就形成了文件碎片,当文件被误删除或者格式化后, ...

  7. 详解Grunt插件之LiveReload实现页面自动刷新(两种方案)

    http://www.jb51.net/article/70415.htm    含Grunt系列教程 这篇文章主要通过两种方案详解Grunt插件之LiveReload实现页面自动刷新,需要的朋友可以 ...

  8. ExportExcel

    package cn.com.jansh.core.util; import java.awt.print.Book; import java.io.BufferedInputStream; impo ...

  9. HDU-1256-画8

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1256 这题做的我好苦,开始题目理解错了,一直都不对,仔细看题,别急,慢慢来,别紧张, 难度到不大,但题 ...

  10. Java数据库连接--JDBC调用存储过程,事务管理和高级应用

    相关链接:Jdbc调用存储过程 一.JDBC常用的API深入详解及存储过程的调用 1.存储过程的介绍 我们常用的操作数据库语言SQL语句在执行的时候要先进行编译,然后执行,而存储过程是在大型数据库系统 ...