学习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 相关文章推荐
javascript下查找父节点的简单方法
Aug 13 Javascript
javascript 手动给表增加数据的小例子
Jul 10 Javascript
jQuery中ajax的post()方法用法实例
Dec 26 Javascript
js实现向右横向滑出的二级菜单效果
Aug 27 Javascript
JS实现仿QQ面板的手风琴效果折叠菜单代码
Sep 11 Javascript
JS实现滑动菜单效果代码(包括Tab,选项卡,横向等效果)
Sep 24 Javascript
js电话号码验证方法
Sep 28 Javascript
js 实现数值的千分位及保存小数方法(推荐)
Aug 01 Javascript
View.post() 不靠谱的地方你知道多少
Aug 29 Javascript
input 标签实现输入框带提示文字效果(两种方法)
Oct 09 Javascript
微信小程序单选radio及多选checkbox按钮用法示例
Apr 30 Javascript
微信小程序onShareTimeline()实现分享朋友圈
Jan 07 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获取根域名方法汇总
2014/10/28 PHP
PHP实现服务器状态监控的方法
2014/12/09 PHP
php上传图片类及用法示例
2016/05/11 PHP
php扩展开发入门demo示例
2019/09/23 PHP
PHP获取真实IP及IP模拟方法解析
2020/11/24 PHP
THREE.JS入门教程(1)THREE.JS使用前了解
2013/01/24 Javascript
javascript实现文本域写入字符时限定字数
2014/02/12 Javascript
JavaScript中的eval()函数使用介绍
2014/12/31 Javascript
Java Mybatis框架入门基础教程
2015/09/21 Javascript
利用jQuery实现漂亮的圆形进度条倒计时插件
2015/09/30 Javascript
JavaScript小技巧整理篇(非常全)
2016/01/26 Javascript
关于javascript中限定时间内防止按钮重复点击的思路详解
2016/08/16 Javascript
AngularJS控制器controller给模型数据赋初始值的方法
2017/01/04 Javascript
解决vue-cli3 使用子目录部署问题
2018/07/19 Javascript
jQuery实现经典的网页3D轮播图封装功能【附源码下载】
2019/02/15 jQuery
JS端基于download.js实现图片、视频时直接下载而不是打开预览
2020/05/09 Javascript
[46:47]2014 DOTA2国际邀请赛中国区预选赛 DT VS HGT
2014/05/22 DOTA
python双向链表实现实例代码
2013/11/21 Python
利用selenium 3.7和python3添加cookie模拟登陆的实现
2017/11/20 Python
Python回文字符串及回文数字判定功能示例
2018/03/20 Python
Python SMTP发送邮件遇到的一些问题及解决办法
2018/10/24 Python
新手入门Python编程的8个实用建议
2019/07/12 Python
python爬虫项目设置一个中断重连的程序的实现
2019/07/26 Python
使用python 的matplotlib 画轨道实例
2020/01/19 Python
python中pandas库中DataFrame对行和列的操作使用方法示例
2020/06/14 Python
Django实现简单的分页功能
2021/02/22 Python
突破canvas语法限制 让他支持链式语法
2012/12/24 HTML / CSS
日本最大的药妆连锁店:Matsukiyo松本清药妆店
2017/11/23 全球购物
优秀学生干部个人的自我评价
2013/10/04 职场文书
基层干部十八大感言
2014/01/19 职场文书
学生打架检讨书大全
2014/01/23 职场文书
2014年十一国庆向国旗敬礼寄语
2014/04/11 职场文书
感恩节活动策划方案
2014/05/16 职场文书
文化产业实施方案
2014/06/07 职场文书
2014年干部培训工作总结
2014/12/17 职场文书
六年级语文教学反思
2016/03/03 职场文书