策略模式:

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

回忆下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. github 创建新项目

    二.GitHub简介 GitHub 可以托管各种Git版本库,并提供一个web界面,但与其它像 SourceForge或Google Code这样的服务不同,GitHub的独特卖点在于从另外一个项目进 ...

  2. Python第三天 序列 数据类型 数值 字符串 列表 元组 字典

    Python第三天 序列  数据类型  数值  字符串  列表  元组  字典 数据类型数值字符串列表元组字典 序列序列:字符串.列表.元组序列的两个主要特点是索引操作符和切片操作符- 索引操作符让我 ...

  3. UVa 10034 - Freckles

    题目大意:给出n个点的坐标(x,y),要求用线段将n个点连接起来,求最小的线段和. 最小生成树问题,用Kruskal算法进行求解,其中用到了并查集.将所有的点连接,构成一张图,对每一条边进行编号,两点 ...

  4. Linux用户和用户组管理总结

    Linux下和用户和用户组管理有关的配置文件: /etc/group Group account information. /etc/gshadow Secure group account info ...

  5. Hybird应用开发实践(一)使用原生/cordova混合项目

    最近准备尝试hybird开发原生应用,因为公司的项目本来就是原生开发的,所以准备选择cordova作为webview嵌入原生项目的开发方式.这里就以mac上整合ios项目为例. 1. 创建cordov ...

  6. JDK中的插入排序

    算法 有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法--插入排序法,插入排序的基本操作就是将一个数据插入到已经排好 ...

  7. 阿里云服务器windows系统C盘一键清理脚本

    @ECHO OFF @echo @echo @echo 清理几个比较多垃圾文件的地方 DEL /F /S /Q "C:\WINDOWS\PCHealth\ERRORREP\QSIGNOFF\ ...

  8. Spring util-namespace下标签相关操作

    java代码 package com.stono.sprtest; import java.util.List; import java.util.Map; import java.util.Set; ...

  9. 内存快照排查OOM,加密时错误方法指定provider方式错误引起的OOM

    写在前面: 最近开始总结内存方面的东西,已经总结以前遇到的一些内存案例分享下,接下来还有几篇,然后是进程/线程相关的,逐渐形成我的知识体系树 如果你有兴趣,可以文章末尾的公众号二维码一起梳理这些信息. ...

  10. Java错题

    加粗为正确答案,绿色为错选答案 1.对于以下代码: for ( int i=0; i<10; i++)  System.out.println(i); for循环后,i的值是多少? A.i不再存 ...