学习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 动态选中下拉框
Nov 26 Javascript
js中单引号与双引号冲突问题解决方法
Oct 04 Javascript
利用js读取动态网站从服务器端返回的数据
Feb 10 Javascript
node.js中的dns.getServers方法使用说明
Dec 08 Javascript
JS中正则表达式要注意lastIndex属性
Aug 08 Javascript
AngularJS自定义过滤器用法经典实例总结
May 17 Javascript
vue组件jsx语法的具体使用
May 21 Javascript
Vue-router的使用和出现空白页,路由对象属性详解
Sep 03 Javascript
layui+jquery支持IE8的表格分页方法
Sep 28 jQuery
微信小程序获取公众号文章列表及显示文章的示例代码
Mar 10 Javascript
基于Vue实现微前端的示例代码
Apr 24 Javascript
vue keep-alive的简单总结
Jan 25 Vue.js
基于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
ThinkPHP Mobile使用方法简明教程
2014/06/18 PHP
Yii2 rbac权限控制操作步骤实例教程
2016/04/29 PHP
php版阿里大于(阿里大鱼)短信发送实例详解
2016/11/30 PHP
php批量删除操作(数据访问)
2017/05/23 PHP
laravel框架的安装与路由实例分析
2019/10/11 PHP
基于jquery的button默认enter事件(回车事件)。
2011/05/18 Javascript
jQuery EasyUI API 中文文档 - EasyLoader 加载器
2011/09/29 Javascript
javascript (用setTimeout而非setInterval)
2011/12/28 Javascript
js中eval详解
2012/03/30 Javascript
js实现页面跳转重定向的几种方式
2014/05/29 Javascript
javascript中解析四则运算表达式的算法和示例
2014/08/11 Javascript
判断JS对象是否拥有某属性的方法推荐
2016/05/12 Javascript
使用jsonp实现跨域获取数据实例讲解
2016/12/25 Javascript
Angularjs中的验证input输入框只能输入数字和小数点的写法(推荐)
2017/08/16 Javascript
jquery 一键复制到剪切板的实例
2017/09/20 jQuery
解决nodejs的npm命令无反应的问题
2018/05/17 NodeJs
jquery ui 实现 tab标签功能示例【测试可用】
2019/07/25 jQuery
微信小程序后端(java)开发流程的详细步骤
2019/11/13 Javascript
vue-admin-template配置快捷导航的代码(标签导航栏)
2020/09/04 Javascript
零基础学Python(一)Python环境安装
2014/08/20 Python
python实现判断数组是否包含指定元素的方法
2015/07/15 Python
Python基于scapy实现修改IP发送请求的方法示例
2017/07/08 Python
Python编程实现的图片识别功能示例
2017/08/03 Python
vscode 远程调试python的方法
2017/12/01 Python
深入理解Django自定义信号(signals)
2018/10/15 Python
Python如何使用Gitlab API实现批量的合并分支
2019/11/27 Python
pytorch制作自己的LMDB数据操作示例
2019/12/18 Python
Python如何实现机器人聊天
2020/09/10 Python
关于探究python中sys.argv时遇到的问题详解
2021/02/23 Python
CSS3的颜色渐变效果的示例代码
2017/09/29 HTML / CSS
移动端适配 使px自动转换rem
2019/08/26 HTML / CSS
Lacoste(法国鳄鱼)加拿大官网:以标志性的POLO衫而闻名
2019/05/15 全球购物
校园歌咏比赛主持词
2014/03/18 职场文书
实习生岗位职责
2014/04/12 职场文书
Django使用channels + websocket打造在线聊天室
2021/05/20 Python
解析Redis Cluster原理
2021/06/21 Redis