学习JavaScript设计模式之策略模式


Posted in Javascript onJanuary 12, 2016

把不变的部分和变化的部分隔开是每个设计模式的主题。

  • 条条大路通罗马。我们经常会遇到解决一件事情有多种方案,比如压缩文件,我们可以使用zip算法、也可以使用gzip算法。其灵活多样,我们可以采用策略模式解决。

一、定义

定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。
基于策略类模式的程序至少由两部分组成。第一个部分是一组策略类,策略类封装了具体的算法,并负责具体的计算过程。第二个部分是环境类Context,Context接收客户的请求,随后把请求委托给某一个策略类。

二、示例

计算奖金。绩效为S的发放4倍工资,绩效为A的发放3倍工资,绩效为B的发放2倍工资。

var strategies = {
 "S": function(salary) {
  return salary * 4;
 },
 "A": function(salary) {
  return salary * 3;
 },
 "B": function(salary) {
  return salary * 2;
 }
};

// 接收请求
var calculateBonus = function(level, salary) {
 return strategies[level](salary);
};

// 测试
console.log(calculateBonus("S", 20000));
console.log(calculateBonus("A", 20000));
console.log(calculateBonus("B", 20000));

三、延伸:表单验证

/* 校验策略对象 */
var validateStrategies = {
 isEmpty: function (val, errorMsg) {
  if (!val) {
   return errorMsg;
  }
 },
 isURL: function (val, errorMsg) {
  if (!new RegExp("^(http:\\/\\/|https:\\/\\/)?([\\w\\-]+\\.)+[\\w\\-]+(\\/[\\w\\-\\.\\/?\\@\\%\\!\\&=\\+\\~\\:\\#\\;\\,]*)?$").test(val)) {
   return errorMsg;
  }
 },
 isEmail: function (val, errorMsg) {
  if (!new RegExp('\\w+((-\\w+)|(\\.\\w+))*\\@[A-Za-z0-9]+((\\.|-)[A-Za-z0-9]+)*\\.[A-Za-z0-9]+').test(val)) {
   return errorMsg;
  }
 },
 isMaxLength: function (val, length, errorMsg) {
  if (val.length > length) {
   return errorMsg;
  }
 },
 isMinLength: function (val, length, errorMsg) {
  if (val.length < length) {
   return errorMsg;
  }
 }
};

/* validator类 */
var validator = function () {
 // 缓存验证策略
 this.cache = [];
};

/**
 * 添加要验证的策略
 * @param dom  要验证的dom元素
 * @param rules  验证规则
 */
validator.prototype.add = function (dom, rules) {
 var self = this;
 for (var i = 0, rule; rule = rules[i++];) {
  (function (rule) {
   var strategyAry = rule.strategy.split(":");  // ["isMaxLength", "10"]
   var errorMsg = rule.errorMsg;     // "内容长度不能超过10"
   self.cache.push(function () {
    var strategy = strategyAry.shift();   // "isMaxLength"
    strategyAry.unshift(dom.value);    // ["1@qq", "10"]
    strategyAry.push(errorMsg);     // ["1@qq", "10", "内容长度不能超过10"]
    return validateStrategies[strategy].apply(dom, strategyAry);
   });
  })(rule);
 }
};

/* 开始校验 */
validator.prototype.start = function () {
 for (var i = 0, validateFunc; validateFunc = this.cache[i++];) {
  var errorMsg = validateFunc();
  if (errorMsg) {
   return errorMsg;
  }
 }
};


// 测试

<label for="email">邮箱:</label><input type="text" name="email" value="1@qq">

var validatorInstance = new validator();
validatorInstance.add(
 document.getElementsByName("email")[0], 
 [{
  strategy: "isEmpty",
  errorMsg: "内容不能为空"
 },{
  strategy: "isMaxLength:10",
  errorMsg: "内容长度不能超过10"
 },{
  strategy: "isEmail",
  errorMsg: "email格式不对"
 }]);
errorMsg = validatorInstance.start();

希望本文所述对大家学习javascript程序设计有所帮助。

Javascript 相关文章推荐
js日期相关函数总结分享
Oct 15 Javascript
引入autocomplete组件时JS报未结束字符串常量错误
Mar 19 Javascript
javascript作用域、作用域链(菜鸟必看)
Jun 16 Javascript
基于JavaScript实现添加到购物车效果附源码下载
Aug 22 Javascript
JS实现焦点图轮播效果的方法详解
Dec 19 Javascript
JS中Array数组学习总结
Jan 18 Javascript
MUI  Scroll插件的使用详解
Apr 13 Javascript
jQuery除指定区域外点击任何地方隐藏DIV功能
Nov 13 jQuery
jquery中ajax请求后台数据成功后既不执行success也不执行error的完美解决方法
Dec 24 jQuery
基于datepicker定义自己的angular时间组件的示例
Mar 14 Javascript
Vue自定义指令封装节流函数的方法示例
Jul 09 Javascript
vuex实现的简单购物车功能示例
Feb 13 Javascript
基于jQuery1.9版本如何判断浏览器版本类型
Jan 12 #Javascript
jQuery版本升级踩坑大全
Jan 12 #Javascript
基于jQuery实现点击最后一行实现行自增效果的表格
Jan 12 #Javascript
7个jQuery最佳实践
Jan 12 #Javascript
实例详解jQuery Mockjax 插件模拟 Ajax 请求
Jan 12 #Javascript
JavaScript实现输入框(密码框)出现提示语
Jan 12 #Javascript
javascript自动恢复文本框点击清除后的默认文本
Jan 12 #Javascript
You might like
PHP程序员面试 切忌急功近利(更需要注重以后的发展)
2010/09/01 PHP
Yii入门教程之Yii安装及hello world
2014/11/25 PHP
php为字符串前后添加指定数量字符的方法
2015/05/04 PHP
yii2带搜索功能的下拉框实例详解
2016/05/12 PHP
ThinkPHP实现更新数据实例详解(demo)
2016/06/29 PHP
JS中confirm,alert,prompt函数使用区别分析
2010/04/01 Javascript
Javascript无阻塞加载具体方式
2013/06/28 Javascript
js实现的Easy Tabs选项卡用法实例
2015/09/06 Javascript
JQuery fileupload插件实现文件上传功能
2016/03/18 Javascript
Vue实现active点击切换方法
2018/03/16 Javascript
React中使用async validator进行表单验证的实例代码
2018/08/17 Javascript
angularJs中跳转到指定的锚点实例($anchorScroll)
2018/08/31 Javascript
vuejs数据超出单行显示更多,点击展开剩余数据实例
2019/05/05 Javascript
利用layer实现表单完美验证的方法
2019/09/26 Javascript
vue Element左侧无限级菜单实现
2020/06/10 Javascript
基于postman获取动态数据过程详解
2020/09/08 Javascript
JS实现点击掉落特效
2021/01/29 Javascript
Python检测字符串中是否包含某字符集合中的字符
2015/05/21 Python
使用python脚本实现查询火车票工具
2018/07/19 Python
python使用tornado实现简单爬虫
2018/07/28 Python
使用PYTHON解析Wireshark的PCAP文件方法
2019/07/23 Python
通过Python实现Payload分离免杀过程详解
2020/07/13 Python
Kenneth Cole官网:纽约时尚优雅品牌
2016/11/14 全球购物
蛋白质世界:Protein World
2017/11/23 全球购物
美国婚礼和派对礼品网站:Kate Aspen(新娘送礼会、迎婴派对)
2018/03/28 全球购物
巴西箱包、背包、钱包和旅行配件购物网站:Inovathi
2019/12/14 全球购物
初中升旗仪式演讲稿
2014/05/08 职场文书
2014乡镇党委副书记对照检查材料思想汇报
2014/10/09 职场文书
教师政风行风自查自纠报告
2014/10/21 职场文书
2014年纪委工作总结
2014/12/05 职场文书
2015年五四青年节活动总结
2015/02/10 职场文书
匿名检举信范文
2015/03/02 职场文书
离婚代理词范文
2015/05/23 职场文书
指导老师鉴定意见
2015/06/05 职场文书
2016教师廉洁从教心得体会
2016/01/13 职场文书
Nginx如何配置多个服务域名解析共用80端口详解
2022/09/23 Servers