学习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判断CSS文件加载完毕的具体实现
Jan 17 Javascript
jQuery获取节点和子节点文本的方法
Jul 22 Javascript
jQuery实现的图片分组切换焦点图插件
Jan 06 Javascript
基于jquery实现智能表单验证操作
May 09 Javascript
js跨域资源共享 基础篇
Jul 02 Javascript
AngularJs 指令详解及示例代码
Sep 01 Javascript
非常实用的vue导航钩子
Mar 20 Javascript
微信小程序实现移动端滑动分页效果(ajax)
Jun 13 Javascript
vue项目使用微信公众号支付总结及遇到的坑
Oct 23 Javascript
BootStrap模态框闪退问题实例代码详解
Dec 10 Javascript
Vue指令之 v-cloak、v-text、v-html实例详解
Aug 08 Javascript
javascript实现倒计时效果
Feb 17 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
关于UEditor编辑器远程图片上传失败的解决办法
2012/08/31 PHP
php表单敏感字符过滤类
2014/12/08 PHP
php实现的任意进制互转类分享
2015/07/07 PHP
PHP编辑器PhpStrom运行缓慢问题
2017/02/21 PHP
JavaScript返回网页中锚点数目的方法
2015/04/03 Javascript
JavaScript中的Math.sin()方法使用详解
2015/06/15 Javascript
JS实现横向拉伸动感伸缩菜单效果代码
2015/09/04 Javascript
详解AngularJS中自定义过滤器
2015/12/28 Javascript
angularjs表格ng-table使用备忘录
2016/03/09 Javascript
基于js里调用函数时,函数名带括号和不带括号的区别
2016/07/28 Javascript
Vue自定义图片懒加载指令v-lazyload详解
2020/12/31 Javascript
Vue中img的src属性绑定与static文件夹实例
2017/05/18 Javascript
JS分页的实现(同步与异步)
2017/09/16 Javascript
webpack4 处理CSS的方法示例
2018/09/03 Javascript
详解如何构建Promise队列实现异步函数顺序执行
2018/10/23 Javascript
vue2.0+SVG实现音乐播放圆形进度条组件
2019/09/21 Javascript
原生js实现商品筛选功能
2019/10/28 Javascript
详解Django 中是否使用时区的区别
2018/06/14 Python
python调用百度语音识别api
2018/08/30 Python
python钉钉机器人运维脚本监控实例
2019/02/20 Python
Python IDE Pycharm中的快捷键列表用法
2019/08/08 Python
python scrapy重复执行实现代码详解
2019/12/28 Python
python PyAUtoGUI库实现自动化控制鼠标键盘
2020/09/09 Python
CSS3 绘制BMW logo实的现代码
2013/04/25 HTML / CSS
香港永安旅游网:Wing On Travel
2017/04/10 全球购物
波兰家居和花园家具专家:4Home
2019/05/26 全球购物
教师自荐书
2013/10/08 职场文书
自考毕业自我鉴定范文
2013/10/27 职场文书
音乐学院硕士生的自我评价分享
2013/11/01 职场文书
中专生自我鉴定
2013/12/17 职场文书
会计电算化大学生职业规划书
2014/02/05 职场文书
函授毕业生自我鉴定范文
2014/03/25 职场文书
2014年党员公开承诺践诺书
2014/03/25 职场文书
医院合作协议书
2014/08/19 职场文书
2015羊年春节慰问信
2015/02/14 职场文书
python使用pycharm安装pyqt5以及相关配置
2022/04/22 Python