学习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函数库)S.Sams Lifexperience ScriptClassLib
Apr 29 Javascript
js中prototype用法详细介绍
Nov 14 Javascript
javascript中字符串的定义示例代码
Dec 19 Javascript
javascript实现简单的分页特效
Aug 12 Javascript
JS实现网页上随滚动条滚动的层效果代码
Nov 04 Javascript
每日十条JavaScript经验技巧(一)
Jun 23 Javascript
详解React中setState回调函数
Jun 14 Javascript
jQuery利用FormData上传文件实现批量上传
Dec 04 jQuery
Vue实现简单的跑马灯
May 25 Javascript
微信小程序实现带放大效果的轮播图
May 26 Javascript
nuxt.js添加环境变量,区分项目打包环境操作
Nov 06 Javascript
解决Antd Table表头加Icon和气泡提示的坑
Nov 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
PHP 判断变量类型实现代码
2009/10/23 PHP
php中使用addslashes函数报错问题的解决方法
2013/02/06 PHP
PHP+Ajax+JS实现多图上传
2016/05/07 PHP
详解yii2实现分库分表的方案与思路
2017/02/03 PHP
RR vs IO BO3 第二场2.13
2021/03/10 DOTA
基于jquery的$.ajax async使用
2011/10/19 Javascript
JS小功能(setInterval实现图片效果显示时间)实例代码
2013/11/28 Javascript
javascript基本类型详解
2014/11/28 Javascript
jquery实现标签支持图文排列带上下箭头按钮的选项卡
2015/03/14 Javascript
理解JavaScript中Promise的使用
2016/01/18 Javascript
Bootstrap表单制作代码
2017/03/17 Javascript
纯原生js实现贪吃蛇游戏
2020/04/16 Javascript
基于JavaScript实现多级菜单效果
2017/07/25 Javascript
JavaScript寄生组合式继承实例详解
2018/01/06 Javascript
详解nuxt sass全局变量(公共scss解决方案)
2018/06/27 Javascript
vue + node如何通过一个Txt文件批量生成MP3并压缩成Zip
2020/06/02 Javascript
Vue实现购物小球抛物线的方法实例
2020/11/22 Vue.js
浅谈python中的getattr函数 hasattr函数
2016/06/14 Python
Python的collections模块中的OrderedDict有序字典
2016/07/07 Python
python解决Fedora解压zip时中文乱码的方法
2016/09/18 Python
Python中定时任务框架APScheduler的快速入门指南
2017/07/06 Python
Pandas数据离散化原理及实例解析
2019/11/16 Python
python判断无向图环是否存在的示例
2019/11/22 Python
Django Admin后台模型列表页面如何添加自定义操作按钮
2020/11/11 Python
美国隐形眼镜网上商店:Lens.com
2019/09/03 全球购物
瑞士图书网站:Weltbild.ch
2019/09/17 全球购物
SQL数据库笔试题
2016/03/08 面试题
武汉世纪畅想数字传播有限公司.NET笔试题
2014/07/22 面试题
优秀的教师个人的中文求职信
2013/09/21 职场文书
大学生的创业计划书就该这么写
2014/01/30 职场文书
推荐信格式要求
2014/05/09 职场文书
软弱涣散基层党组织整改方案
2014/10/25 职场文书
庆七一活动简报
2015/07/20 职场文书
jQuery实现影院选座订座效果
2021/04/13 jQuery
Jupyter Notebook内使用argparse报错的解决方案
2021/06/03 Python
Vue项目打包、合并及压缩优化网页响应速度
2021/07/07 Vue.js