学习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创建对象的几种常用方式小结(推荐)
Oct 24 Javascript
JavaScript子窗口ModalDialog中操作父窗口对像
Dec 11 Javascript
javascript验证上传文件的类型限制必须为某些格式
Nov 14 Javascript
javascript setinterval 的正确语法如何书写
Jun 17 Javascript
快速入门Vue
Dec 19 Javascript
基于vue2.0实现简单轮播图
Nov 27 Javascript
利用nginx + node在阿里云部署https的步骤详解
Dec 19 Javascript
JS实现延迟隐藏功能的方法(类似QQ头像鼠标放上展示信息)
Dec 28 Javascript
AngularJS基于MVC的复杂操作实例讲解
Dec 31 Javascript
setTimeout时间设置为0详细解析
Mar 13 Javascript
JavaScript两种计时器的实例讲解
Jan 31 Javascript
Node.js中文件系统fs模块的使用及常用接口
Mar 06 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
收音机发烧友应当熟知的100条知识
2021/03/02 无线电
php下检测字符串是否是utf8编码的代码
2008/06/28 PHP
Python中使用django form表单验证的方法
2017/01/16 PHP
PHP框架Laravel中实现supervisor执行异步进程的方法
2017/06/07 PHP
yii gridview实现时间段筛选功能
2017/08/15 PHP
Laravel框架实现抢红包功能示例
2019/10/31 PHP
laravel 框架结合关联查询 when()用法分析
2019/11/22 PHP
innerhtml用法 innertext用法 以及innerHTML与innertext的区别
2009/10/26 Javascript
javascript使用百度地图api和html5特性获取浏览器位置
2014/01/10 Javascript
node.js中的fs.ftruncate方法使用说明
2014/12/15 Javascript
c#程序员对TypeScript的认识过程
2015/06/19 Javascript
node.js+jQuery实现用户登录注册AJAX交互
2017/04/28 jQuery
JavaScript实现多张图片放大镜效果示例【不限定图片尺寸,rem单位】
2019/05/14 Javascript
js console.log打印对象时属性缺失的解决方法
2019/05/23 Javascript
create-react-app中添加less支持的实现
2019/11/15 Javascript
全面解析js中的原型,原型对象,原型链
2021/01/25 Javascript
给Python的Django框架下搭建的BLOG添加RSS功能的教程
2015/04/08 Python
python的Crypto模块实现AES加密实例代码
2018/01/22 Python
Python实现的简单计算器功能详解
2018/08/25 Python
在python里从协程返回一个值的示例
2019/02/19 Python
Python数据类型之Set集合实例详解
2019/05/07 Python
python3操作注册表的方法(Url protocol)
2020/02/05 Python
严选全球尖货,立足香港:Bonpont宝盆
2018/07/24 全球购物
Europcar澳大利亚官网:全球汽车租赁领域的领导者
2019/03/24 全球购物
C#面试题问题集
2016/04/02 面试题
绘画设计学生的个人自我评价
2013/09/20 职场文书
会展中心部门工作职责
2013/11/27 职场文书
关于圣诞节的广播稿
2014/01/26 职场文书
酒店副总经理岗位职责范本
2014/02/04 职场文书
班主任高考寄语
2015/02/26 职场文书
北京爱情故事观后感
2015/06/12 职场文书
2019旅游导游工作总结
2019/06/27 职场文书
万能密码的SQL注入漏洞其PHP环境搭建及防御手段
2021/09/04 SQL Server
SpringCloud Feign请求头删除修改的操作代码
2022/03/20 Java/Android
基于Apache Hudi在Google云构建数据湖平台的思路详解
2022/04/07 Servers
Go中使用gjson来操作JSON数据的实现
2022/08/14 Golang