学习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实现的UBB编码函数
Mar 09 Javascript
JavaScript 函数调用规则
Sep 14 Javascript
影响jQuery使用的14个方面
Sep 01 Javascript
JS实现鼠标箭头变成一个燃烧烛光效果的方法
Feb 28 Javascript
Node.js环境下编写爬虫爬取维基百科内容的实例分享
Jun 12 Javascript
谈谈target=_new和_blank的不同之处
Oct 25 Javascript
Vue 父子组件、组件间通信
Mar 08 Javascript
JS Testing Properties 判断属性是否在对象里的方法
Oct 01 Javascript
如何重置vue打印变量的显示方式
Dec 06 Javascript
Vue完整项目构建(进阶篇)
Feb 10 Javascript
关于JavaScript中高阶函数的魅力详解
Sep 07 Javascript
javascript面向对象三大特征之多态实例详解
Jul 24 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生成静态HTML文档的原理
2012/10/29 PHP
基于PHP中的常用函数回顾
2013/07/11 PHP
php导入导出excel实例
2013/10/25 PHP
windows下安装php的memcache模块的方法
2015/04/07 PHP
用JavaScript将从数据库中读取出来的日期型格式化为想要的类型。
2009/08/15 Javascript
JavaScript高级程序设计(第3版)学习笔记3 js简单数据类型
2012/10/11 Javascript
javascript中的if语句使用介绍
2013/11/20 Javascript
jQuery循环动画与获取组件尺寸的方法
2015/02/02 Javascript
Web前端开发工具——bower依赖包管理工具
2016/03/29 Javascript
工作中比较实用的JavaScript验证和数据处理的干货(经典)
2016/08/03 Javascript
BootstrapValidator不触发校验的实现代码
2016/09/28 Javascript
vue2.0 自定义 饼状图 (Echarts)组件的方法
2018/03/02 Javascript
基于ionic实现下拉刷新功能
2018/05/10 Javascript
vue better scroll 无法滚动的解决方法
2018/06/07 Javascript
vue-cli设置css不生效的解决方法
2020/02/07 Javascript
详细介绍Python语言中的按位运算符
2013/11/26 Python
Python探索之修改Python搜索路径
2017/10/25 Python
简单实现python数独游戏
2018/03/30 Python
利用python和ffmpeg 批量将其他图片转换为.yuv格式的方法
2019/01/08 Python
python 多个参数不为空校验方法
2019/02/14 Python
Pycharm修改python路径过程图解
2020/05/22 Python
python利用 keyboard 库记录键盘事件
2020/10/16 Python
HTML5语音识别标签写法附图
2013/11/18 HTML / CSS
GWT都有什么特性
2016/12/02 面试题
银行演讲稿范文
2014/01/03 职场文书
一份婚庆公司创业计划书
2014/01/11 职场文书
创建卫生先进单位实施方案
2014/03/10 职场文书
《雕塑之美》教学反思
2014/04/24 职场文书
团队拓展活动方案
2014/08/28 职场文书
债务纠纷委托书
2014/08/30 职场文书
农村党支部书记司法四风问题对照检查材料
2014/09/26 职场文书
机关作风建设整改方案
2014/10/27 职场文书
毕业感言怎么写
2015/07/31 职场文书
党员观看《筑梦中国》心得体会
2016/01/18 职场文书
基于Redis6.2.6版本部署Redis Cluster集群的问题
2022/04/01 Redis
Promise静态四兄弟实现示例详解
2022/07/07 Javascript