首页 > 编程语言 >【JS】168-JavaScript设计模式——策略模式

【JS】168-JavaScript设计模式——策略模式

时间:2022-10-13 15:35:24浏览次数:41  
标签:num 验证 JavaScript JS 算法 validator let 设计模式 type

【JS】168-JavaScript设计模式——策略模式_数据

五、策略模式(Strategy Pattern)

1.概念介绍

策略模式(Strategy Pattern):封装一系列算法,支持我们在运行时,使用相同接口,选择不同算法。它的目的是为了将算法的使用与算法的实现分离开来

策略模式通常会有两部分组成,一部分是策略类,它负责实现通用的算法,另一部分是环境类,它用户接收客户端请求并委托给策略类。

2.优缺点

2.1优点

  • 有效地避免多重条件选择语句;
  • 支持开闭原则,将算法独立封装,使得更加便于切换、理解和扩展;
  • 更加便于代码复用;

2.2缺点

  • 策略类会增多;
  • 所有策略类都需要对外暴露;

3.基本案例

我们可以很简单的将策略和算法直接做映射:

1. ​​let add = {​​
2. ​​ "add3" : (num) => num + 3,​​
3. ​​ "add5" : (num) => num + 5,​​
4. ​​ "add10": (num) => num + 10,​​
5. ​​}​​
6. ​​let demo = (type, num) => add[type](num);​​
7. ​​console.log(demo('add3', 10)); // 13​​
8. ​​console.log(demo('add10', 12)); // 22​​

然后我们再把每个策略的算法抽出来:

4.表单验证案例

1. let fun3  = (num) => num + 3;​​
2. ​​let fun5 = (num) => num + 5;​​
3. ​​let fun10 = (num) => num + 10;​​
4. ​​let add = {​​
5. ​​ "add3" : (num) => fun3(num),​​
6. ​​ "add5" : (num) => fun5(num),​​
7. ​​ "add10": (num) => fun10(num),​​
8. ​​}​​
9. ​​let demo = (type, num) => add[type](num);​​
10. ​​console.log(demo('add3', 10)); // 13​​
11. ​​console.log(demo('add10', 12)); // 22​​

我们需要使用策略模式,实现一个处理表单验证的方法,无论表单的具体类型是什么都会调用验证方法。我们需要让验证器能选择最佳的策略来处理任务,并将具体的验证数据委托给适当算法。

我们假设需要验证下面的表单数据的有效性:

1. ​​let data = {​​
2. ​​ name : 'pingan',​​
3. ​​ age : 'unknown',​​
4. ​​ nickname: 'leo',​​
5. ​​}​​

这里需要先配置验证器,对表单数据中不同的数据使用不同的算法:

1. ​​validator.config = {​​
2. ​​ name : 'isNonEmpty',​​
3. ​​ age : 'isNumber',​​
4. ​​ nickname: 'isAlphaNum',​​
5. ​​}​​

并且我们需要将验证的错误信息打印到控制台:

1. ​​validator.validate(data);​​
2. ​​if(validator.hasErrors()){​​
3. ​​ console.log(validator.msg.join('\n'));​​
4. ​​}​​

接下来我们才要实现 ​​validator​​​中具体的验证算法,他们都有一个相同接口 ​​validator.types​​​,提供 ​​validate()​​​方法和 ​​instructions​​帮助信息:

1. ​​// 非空值检查​​
2. ​​validator.types.isNonEmpty = {​​
3. ​​ validate: function(value){​​
4. ​​ return value !== '';​​
5. ​​ }​​
6. ​​ instructions: '该值不能为空'​​
7. ​​}​​
2. 
3. ​​// 数值类型检查​​
4. ​​validator.types.isNumber = {​​
5. ​​ validate: function(value){​​
6. ​​ return !isNaN(value);​​
7. ​​ }​​
8. ​​ instructions: '该值只能是数字'​​
9. ​​}​​
10.
11. ​​// 检查是否只包含数字和字母​​
12. ​​validator.types.isAlphaNum = {​​
13. ​​ validate: function(value){​​
14. ​​ return !/[^a-z0-9]/i.test(value);​​
15. ​​ }​​
16. ​​ instructions: '该值只能包含数字和字母,且不包含特殊字符'​​
17. ​​}​​

最后就是要实现最核心的 ​​validator​​对象:

总结这个案例,我们可以看出 ​​validator​​​对象是通用的,需要增强 ​​validator​​​对象的方法只需添加更多的类型检查,后续针对每个新的用例,只需配置验证器和运行 ​​validator()​​方法就可以。

1. let validator = {​​
2. ​​ types: {}, // 所有可用的检查​​
3. ​​ msg:[], // 当前验证的错误信息​​
4. ​​ config:{}, // 验证配置​​
5. ​​ validate: function(data){ // 接口方法​​
6. ​​ let type, checker, result;​​
7. ​​ this.msg = []; // 清空错误信息​​
8. ​​ for(let k in data){​​
9. ​​ if(data.hasOwnProperty(k)){​​
10. ​​ type = this.config[k];​​
11. ​​ checker = this.types[type];​​
12. ​​ if(!type) continue; // 不存在类型 则 不需要验证​​
13. ​​ if(!checker){​​
14. ​​ throw {​​
15. ​​ name: '验证失败',​​
16. ​​ msg: `不能验证类型:${type}`​​
17. ​​ }​​
18. ​​ }​​
19. ​​ result = checker.validate(data[k]);​​
20. ​​ if(!result){​​
21. ​​ this.msg.push(`无效的值:${k},${checker.instructions}`);​​
22. ​​ }​​
23. ​​ }​​
24. ​​ }​​
25. ​​ return this.hasErrors();​​
26. ​​ }​​
27. ​​ hasErrors: function(){​​
28. ​​ return this.msg.length != 0;​​
29. ​​ }​​
30. ​​}​​

5.小结

日常开发的时候,还是需要根据实际情况来选择设计模式,而不能为了设计模式而去设计模式。通过上面的学习,我们使用策略模式来避免多重条件判断,并且通过开闭原则来封装方法。我们应该多在开发中,逐渐积累自己的开发工具库,便于以后使用。

参考资料

  1. 《JavaScript Patterns》

【JS】168-JavaScript设计模式——策略模式_数据_02

标签:num,验证,JavaScript,JS,算法,validator,let,设计模式,type
From: https://blog.51cto.com/u_11887782/5753519

相关文章

  • 【JS】166-JavaScript设计模式——迭代器模式
    三、迭代器模式(IteratorPattern)1.概念介绍迭代器模式(IteratorPattern) 是提供一种方法,顺序访问一个聚合对象中每个元素,并且不暴露该对象内部。这种模式属于行为型模式......
  • 【JS】172-JavaScript设计模式——观察者模式
    九、观察者模式(ObserverPatterns)1.概念介绍观察者模式(ObserverPatterns) 也称订阅/发布(subscriber/publisher)模式,这种模式下,一个对象订阅定一个对象的特定活动,并在状......
  • 【JS】170-JavaScript设计模式——代理模式
    七、代理模式(ProxyPattern)1.概念介绍代理模式(ProxyPattern) 为其他对象提供一种代理,来控制这个对象的访问,代理是在客户端和真实对象之间的介质。简单的理解:如我们需要......
  • videojs播放直播
    index.html引入css和js<linkhref="https://cdn.bootcdn.net/ajax/libs/video.js/7.10.1/alt/video-js-cdn.min.css"rel="stylesheet"><scripttype="text/javascrip......
  • 【JS】222-JS 函数的 6 个基本术语
    英文:Martin Novák 译文:reahinkhttps://zhuanlan.zhihu.com/p/61868946让我们谈谈什么是:lambdas(匿名函数)、first-classfunctions(头等函数)、higher-orderfunctions(高阶......
  • 45. JS Ajax请求(简明教程)
    1.前言Ajax全称“AsynchronousJavaScriptandXML”,译为“异步JavaScript和XML”,程序员们习惯称之为“阿贾克斯”,它并不是一种技术,而是多种技术的综合体,其中包括Ja......
  • 46. JS类型转换(强制类型转换+隐式类型转换)
    1.前言JavaScript 中有五种基本数据类型(其中包括String、Number、Boolean、Function、Symbol)、三种对象类型(其中包括Object、Date、Array)和两种特殊类型(其中包括Nul......
  • 【JS】80-如何优雅处理前端异常?
    前端一直是距离用户最近的一层,随着产品的日益完善,我们会更加注重用户体验,而前端异常却如鲠在喉,甚是烦人。一、为什么要处理异常?异常是不可控的,会影响最终的呈现结果,但是我们......
  • 【JS】89-用JavaScript实现的5个常见函数
    前言    在学习 JavaScript,或者前端面试中,有人会问你节流函数、防抖函数、递归函数等,本文分享了5个常见函数,希望对你有所帮助。    在 JavaScript 中有一些问题......
  • js时间戳,获取日期的总毫秒值
    时间戳vardate=newDate();console.log(date.valueOf());//valueof返回对象的原始值,date对象的原始值就是毫秒console.log(date.getTime());//返回一个时间的格林威......