浅谈JavaScript中策略模式的使用:什么是设计模式,什么是策略模式策略模式在JavaScript中的应用(使用策略模式来封装百度AI识别调用)策略模式在Vue组件封装中的应用(使用策略模式封装Select组件)什么是设计模式?想象一个电子爱好者。尽管他没有接受过正规培训,但随着时间的推移,他设计并制造了许多有用的电子设备。:业余无线电、盖革计数器、警报器等。有一天,爱好者决定回到学校攻读电子学学位,以获得对他的才华的正式认可。随着课程的展开,这位发烧友突然发现课程内容似曾相识。熟悉的不是术语或措辞方式,而是其背后的概念。爱好者不断学习一些他以前不知道的名字和原理,但实际上他已经用了很多年了。整个过程无非就是一次又一次的顿悟。DesignPatternMeditation,JohnVlissides,Chapter1,Section1.2我们在写代码的时候一定遇到过很多类似的场景。随着阅历的增加,我们对这些常见场景的处理也越来越熟练,甚至总结出了有针对性的“套路”。下次遇到此类问题,我们可以直接用“套路”来解决,省心省力。这些在软件开发过程中逐渐积累起来的“套路”,就是设计模式。设计模式的目标之一是提高代码的可重用性、可扩展性和可维护性。正因如此,虽然有时候我们对某种设计模式并不了解,但在阅读相关书籍或文章后,会有一种恍然大悟的“啊,原来这就是设计模式”。如果看完本文你也有同感,那么恭喜你,你已经在高效程序员的道路上一路狂奔了。什么是策略模式策略模式是一种简单但常用的设计模式,应用场景非常广泛。我们先来了解一下策略模式的概念,然后通过代码示例来更清楚地理解它。策略模式由两部分组成:一是封装不同策略的策略组,二是Context。Context具有通过组合和委托来执行策略的能力,从而实现可重用性、可扩展性和可维护性,避免大量的复制和粘贴工作。策略模式的一个典型应用场景是表单验证中验证规则的封装。下面我们来看一个简单的例子:粗略的表单验证一个常见的登录表单代码如下:手机号码密码登录上面的代码,虽然功能没问题,但是但缺点也很明显:代码中到处都是if语句,缺乏灵活性:每次新增类型或修改原有的验证规则,都需要更改loginForm.onsubmit里面的代码以及其他逻辑的复用性同样糟糕的是:如果有其他形式使用相同的规则,则此代码无法重用,只能复制。当验证规则发生变化时,比如上面的正则验证不匹配虚拟运营商的14/17段,我们需要手动同步多个代码变化(Ctrl+C/Ctrl+V)。优秀的表单验证接下来,我们通过strategy模式的思路重写上面的代码,首先将验证逻辑抽取出封装成一个strategy组:varstrategies={isNonEmpty:function(value,errorMsg){if(value===''||value===null){returnerrorMsg;}},isMobile:function(value,errorMsg){//手机号格式if(!/(^1[3|4|5|7|8][0-9]{9}$)/.test(value)){returnerrorMsg;}},minLength:function(value,length,errorMsg){if(value.lengthdata(){return{selectedValue:undefined,选项:[],action:"",};},props:{//暴露给外部select-typeselectType:{type:String},},created(){//获取optionsthis.valuation();},方法:{optionChanged(){this.$emit(this.action,this.selectedValue);},setOptions(option){this.$store.dispatch(this.action,option);},valuation(){//获取optionsData}},外部组件调用方式如下:strategies然后定义策略组:letstrategies={source:{action:"sourceOption",getOptions:function(){//Pulloptions}},product:{action:"productOption",getOptions:function(){//Pulloptions}},...}asynchronous至此组件的基本结构已经清晰,但是还有一个问题m:加载组件时,它是options是异步拉取的,页面初始化的时候可能还没有返回options,所以select的options还是空的,所以这里要修改代码,同步获取options://policygroupmodificationsource:{action:"sourceOption",getOptions:asyncfunction(){//awaitpullsoptions}},//组件修改methods:{...asyncvaluation(){...}}继续优化但我们不需要pull我们每次加载一个组件时的options,如果这些options也在其他组件或者页面中使用,那么可以考虑将它们存储在vuex中。最初的想法是高层组件,即定义一个封装好的select模板,通过高层组件扩展其数据源和action(变化部分)。但是,这个思路在Vue上不是那么好(主要是槽不好处理。)所以考虑策略模式重写组件总结通过上面两个例子,我们可以看出:策略模式符合开闭原则如果你需要在代码中写很多if-else语句,然后考虑使用策略模式如果多个组件(类)仅在它们的行为上不同,请考虑策略模式