当前位置: 首页 > Web前端 > vue.js

深入浅出地解释js中的策略模式

时间:2023-03-31 17:20:04 vue.js

官方的定义是:定义一系列算法,封装起来,相互替换。谈人(⊙?⊙):就是把看似无关的代码进行抽取、封装和复用,让它们更容易理解和扩展。常用于if判断、switch枚举、数据字典等流程判断语句。使用策略模式来计算等级在游戏中,我们每完成一局游戏就对用户的等级进行评估,比如S级4次经验,A级3次经验,B级2次经验,以及其他1次经验,用函数来表达如下:functiongetExperience(level,experience){if(level=='S'){return4*experience}if(level=='A'){return3*experience}if(level=='B'){return2*experience}returnexperience}可以看出getExperience函数的各种if条件判断,复用性差。我们按照策略模式封装复用的思想重写。//改为策略模式,分成两个函数写conststrategy={'S':function(experience){return4*experience},'A':function(experience){return3*experience},'B':function(experience){return2*experience}}//getExperience可以重复使用functiongetExperience(strategy,level,experience){return(levelinstrategy)?strategy[level](experience):experience}vars=getExperience(strategy,'S',100)vara=getExperience(strategy,'A',100)console.log(s,a)//在400和300之后分为两个功能,策略对象解耦,扩展性强。在vue数据驱动视图更新的updater更新器中使用时,使用的是strategy模式。如果想了解更多vue的底层原理,可以参考github上的一篇文章?MVVM实现//指令处理集合varcompileUtil={//v-text更新视图原理text:function(node,vm,exp){this.bind(node,vm,exp,'text');},//v-html更新视图原理html:function(node,vm,exp){this.bind(node,vm,exp,'html');},//v-class绑定原理class:function(node,vm,exp){this.bind(node,vm,exp,'class');},bind:function(node,vm,exp,dir){//不同命令触发视图更新varupdaterFn=updater[dir+'Updater'];updaterFn&&updaterFn(node,this._getVMVal(vm,exp));newWatcher(vm,exp,function(value,oldValue){updaterFn&&updaterFn(node,value,oldValue);});}......}使用策略模式验证表单常见的表单验证是使用if和else处理语句来判断用户输入的数据是否符合验证规则,而在Elementui中,基于async-validator库,你只需要需要通过rule属性传入约定的校验规则进行校验。方便快捷,可重复使用。下面我们根据策略模式模仿一个验证方式。//我们写一个表单form

首先定义验证规则conststrategies={//非空noEmpty:function(value,errMsg){if(value===''){returnerrMsg}},//最小长度minLength:function(value,length,errMsg){if(!value||value.lengthlength){returnerrMsg}}}thensetvalidator//创建验证器varValidator=function(strategies){this.strategies=strategiesthis.cache=[]//storeValidationrules}//添加验证规则Validator.prototype.add=function(dom,rules){rules.forEach(item=>{this.cache.push(()=>{letvalue=dom.valueletarr=item.rule.split(':')letname=arr.shift()letparams=[value,...arr,item.errMsg]//apply确保上下文一致性returnthis.strategies[name].apply(dom,params)})})}//验证结果Validator.prototype.validate=function(dom,rules,errMsg){//遍历缓存中的验证函数for(leti=0,validateFun;validateFun=this.cache[i++];){constmessage=validateFun()//返回错误信息,终止验证并抛出异常if(message)returnmessage}}最后执行验证varform=document.querySelector("form")//提交表单form.onsubmit=function(event){event.preventDefault()//判断验证结果constmessage=validate()consttip=document.getElementById('tip')if(message){tip.innerHTML=messagetip.style.color='red'}else{tip.innerHTML='验证通过!'tip.style.color='green'}}//验证函数functionvalidate(){//实例验证Validatorconstvalidator=newValidator(strategies)//添加验证规则validator.add(form.username,[{rule:'noEmpty',errMsg:'Usernamecannotbeempty!'},{rule:'minLength:3',errMsg:'用户名长度大于3!'}])validator.add(form.password,[{rule:'minLength:6',errMsg:'密码长度大于6!'},{rule:'maxLength:10',errMsg:'Themaximumpasswordlengthis10!'}])//验证并返回结果returnvalidator.validate()}如上所示,我们可以自定义添加strategies对象Validationrules的属性是可以复用的,极大的方便了日常开发!