学习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 相关文章推荐
用jquery与css打造个性化的单选框和复选框
Oct 20 Javascript
js实现幻灯片播放图片示例代码
Nov 07 Javascript
JS在IE下缺少标识符的错误
Jul 23 Javascript
javascript比较两个日期相差天数的方法
Jul 24 Javascript
javascript实现C语言经典程序题
Nov 29 Javascript
AngularJS删除路由中的#符号的方法
Sep 20 Javascript
Bootstrap CSS组件之大屏幕展播
Dec 17 Javascript
vue中使用localstorage来存储页面信息
Nov 04 Javascript
Angular2.0/4.0 使用Echarts图表的示例代码
Dec 07 Javascript
Node.js 使用request模块下载文件的实例
Sep 05 Javascript
解决百度Echarts图表坐标轴越界的方法
Oct 17 Javascript
浅谈Vue.js组件(二)
Apr 09 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 ckeditor上传图片文件名乱码解决方法
2013/11/15 PHP
一个php短网址的生成代码(仿微博短网址)
2014/05/07 PHP
javascript数组与php数组的地址传递及值传递用法实例
2015/01/22 PHP
SinaEditor使用方法详解
2013/12/28 Javascript
Javascript模拟加速运动与减速运动代码分享
2014/12/11 Javascript
jQuery在页面加载时动态修改图片尺寸的方法
2015/03/20 Javascript
基于JS实现Android,iOS一个手势动画效果
2016/04/27 Javascript
微信小程序 wxapp内容组件 icon详细介绍
2016/10/31 Javascript
angular中实现控制器之间传递参数的方式
2017/04/24 Javascript
详解webpack中的hash、chunkhash、contenthash区别
2018/01/05 Javascript
vue百度地图 + 定位的详解
2019/05/13 Javascript
jQuery实现轮播图效果
2019/11/26 jQuery
[41:21]夜魇凡尔赛茶话会 第三期02:看图识人
2021/03/11 DOTA
python smtplib模块实现发送邮件带附件sendmail
2018/05/22 Python
Python调用C语言的实现
2019/07/26 Python
HTML页面中添加Canvas标签示例
2015/01/01 HTML / CSS
Harrods英国:世界领先的奢侈品百货商店
2020/09/23 全球购物
银行柜员应聘推荐信范文
2013/11/24 职场文书
2014年上半年工作自我评价
2014/01/18 职场文书
工程招投标邀请书
2014/01/30 职场文书
物控部经理职务说明书
2014/02/25 职场文书
超市开学活动方案
2014/03/01 职场文书
简单的项目建议书模板
2014/03/12 职场文书
中药专业自荐信范文
2014/03/18 职场文书
运动会开幕式主持词
2014/03/28 职场文书
委托协议书范本
2014/04/22 职场文书
会计学专业自荐信
2014/06/25 职场文书
应届生自荐信
2014/06/30 职场文书
2014年最新大专生职业生涯规划书范文
2014/09/13 职场文书
2014年会计个人工作总结
2014/11/24 职场文书
五年级下册复习计划
2015/01/19 职场文书
2015公司年度工作总结
2015/05/14 职场文书
浅谈redis五大数据结构和使用场景
2021/04/12 Redis
CSS实现切角+边框+投影+内容背景色渐变效果
2021/11/01 HTML / CSS
Pandas实现批量拆分与合并Excel的示例代码
2022/05/30 Python
浅谈MySql update会锁定哪些范围的数据
2022/06/25 MySQL