学习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实现的原图对比窗帘效果
Jun 15 Javascript
js实现当前输入框高亮显示的方法
Aug 19 Javascript
JavaScript引用类型和基本类型详解
Jan 06 Javascript
Jquery on绑定的事件 触发多次实例代码
Dec 08 Javascript
又一款MVVM组件 构建自己的Vue组件(2)
Mar 13 Javascript
利用node.js本地搭建HTTP服务器
Apr 19 Javascript
js轮播图透明度切换(带上下页和底部圆点切换)
Apr 27 Javascript
使用canvas进行图像编辑的实例
Aug 29 Javascript
微信小程序用户位置权限的获取方法(拒绝后提醒)
Nov 15 Javascript
js实现视图和数据双向绑定的方法分析
Feb 05 Javascript
JavaScript如何实现监听键盘输入和鼠标监点击
Jul 20 Javascript
微信小程序实现modal弹出框遮罩层组件(可带文本框)
Dec 20 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
一个用于mysql的数据库抽象层函数库
2006/10/09 PHP
discuz 首页四格:最新话题+最新回复+热门话题+精华文章插件
2007/08/19 PHP
PHP无敌近乎加密方式!
2010/07/17 PHP
php三维数组去重(示例代码)
2013/11/26 PHP
PHP图片处理之使用imagecopyresampled函数裁剪图片例子
2014/11/19 PHP
ThinkPHP入口文件设置及相关注意事项分析
2014/12/05 PHP
php实现表单多按钮提交action的处理方法
2015/10/24 PHP
Laravel框架集成UEditor编辑器的方法图文与实例详解
2019/04/17 PHP
在JavaScript中使用inline函数的问题
2007/03/08 Javascript
番茄的表单验证类代码修改版
2008/07/18 Javascript
js 左右悬浮对联广告特效代码
2014/12/12 Javascript
教你用十行node.js代码读取docx的文本
2017/03/08 Javascript
vue.js开发环境搭建教程
2017/05/04 Javascript
学习使用Bootstrap输入框、导航、分页等常用组件
2017/05/11 Javascript
vue鼠标悬停事件实例详解
2019/04/01 Javascript
详解在Javascript中进行面向切面编程
2019/04/28 Javascript
koa-router路由参数和前端路由的结合详解
2019/05/19 Javascript
js+springMVC 提交数组数据到后台的实例
2019/09/21 Javascript
使用Layer组件弹出多个对话框(非嵌套)与关闭及刷新的例子
2019/09/25 Javascript
angular组件间通讯的实现方法示例
2020/05/07 Javascript
[49:21]2018DOTA2亚洲邀请赛3月30日 小组赛B组 Effect VS iG
2018/03/31 DOTA
Python复制目录结构脚本代码分享
2015/03/06 Python
讲解Python中的标识运算符
2015/05/14 Python
NumPy 如何生成多维数组的方法
2018/02/05 Python
python爬虫豆瓣网的模拟登录实现
2019/08/21 Python
Python实现搜索算法的实例代码
2020/01/02 Python
python nohup 实现远程运行不宕机操作
2020/04/16 Python
python三引号如何输入
2020/07/06 Python
Python 字典一个键对应多个值的方法
2020/09/29 Python
法国在线宠物店:zooplus.fr
2018/02/23 全球购物
白酒市场开发计划书
2014/01/09 职场文书
推广活动策划方案
2014/08/23 职场文书
办理信用卡收入证明范例
2014/09/13 职场文书
委托书的写法
2014/09/16 职场文书
2015年暑假工作总结
2015/07/13 职场文书
图书馆义工感想
2015/08/07 职场文书