栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > JavaScript

javascript设计模式--策略模式之输入验证

JavaScript 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

javascript设计模式--策略模式之输入验证

策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算饭的客户.

先定义一个简单的输入表单:



  
    
    
      .form{
 width: px;
 height: px;
 #margin: px auto;
      }
      .form-item-label{
 width:px;
 text-align: right;
 float: left;
      }
      .form-item-input{
 float: left;
      }
      .form-item{
 width: % ;
 height: px;
 line-height: px;
      }
    
  
  
    
      
 用户名:
 
      
      
 密码:
 
      
      
 确认密码:
 
      
      
 邮箱:
 
      
    
    

 一般在页面上编辑信息后的提交动作中,都需要对输入的信息进行验证,会看到把很多负责check的代码写在提交函数中或者写在一个独立的check函数中。

比如像下面这样。      

 $(document).ready(function(){
 $('#submit').bind('click', doSubmit);
      });
      function doSubmit(){
 var eleUserName = document.getElementById('userName');
 if(eleUserName.value === '') {
   alert('用户名不能为空');
   return;
 }
 if(eleUserName.length < 6) {
   alert('用户名长度不能少于6个字符');
   return;
 }
 if(eleUserName.length > 6) {
   alert('用户名长度不能多于20个字符');
   return;
 }
      }

这样的写法功能上肯定能满足要求,但是,会存在几个问题:

1.如果我要在其他页面上使用,那就要将代码进行复制,所谓的复用就变成了复制,代码会存在大量重复。好一点的会把check代码分类整理封装,单还会存在较多的重复复制。

2.如果我要增加一个输入验证,那么就要直接修改提交函数,该函数会显的臃肿,并且是破坏“开闭”原则的。

3.如果修改了提交函数,就要将函数设计的测试全都覆盖一遍,因为,不知道何时就会发生误改或者未知的情况。

改造步骤:

1.将每个验证逻辑看成是一个验证策略并封装成每个验证策略函数,函数参数保持一致,可以接受dom元素,被验证的值,错误消息,定制参数。

2.定义验证器,可将验证策略函数导入,也可以添加。

3.验证器提供验证方法,用于验证时的调用,其内部调用具体的验证策略函数。

4.验证调用。

步骤1.

把每一个if都看成一种校验的业务规则,把每种业务规则作为一个单独的策略函数,将所有的策略函数封装成一个策略对象。       

 var validationStrategies = {
 isNoEmpty: function(element, errMsg, value) {
   if(value === '') {
     return this.buildInvalidObj(element, errMsg, value );
   }
 },
 minLength: function(element, errMsg, value, length) {
   if(value.length < length){
     return this.buildInvalidObj(element, errMsg, value);
   }
 },
 maxLength: function(element, errMsg, value, length) {
   if(value.length > length){
     return this.buildInvalidObj(element, errMsg, value);
   }
 },
 isMail: function(element, errMsg, value, length) {
   var reg = /^(w-*.*)+@(w-?)+(.w{2,})+$/;
   if(!reg.test(value)){
     return this.buildInvalidObj(element, errMsg, value);
   }
 }
      };

所有函数的参数的前3个都保持一致,而且是必须的,表示被验证的DOM元素,错误消息,被验证的值,第4个开始由函数自身的验证规则决定定制的参数,可有多个参数。

“buildInvalidObj”方法只是把前3个参数打成一个错误对象进行返回,只要验证不通过就会返回这个错误对象。

根据依赖倒置原则,高层次的模块不应该依赖于低层次的模块,因此不能让验证的调用方直接使用。

通过验证器的方式进行封装和抽象。

步骤2:

定义验证器,可以将所有验证策略导入其内,也可以单独添加验证策略函数。         

//输入验证器
      function InputValidators(){
 this.validators = [];
 this.strategies = {};
      }
      //从策略对象导入验证策略函数
      //参数:
      // strategies: 包含各种策略函数的对象
      InputValidators.prototype.importStrategies = function(strategies) {
 for(var strategyName in strategies) {
   this.addValidationStrategy(strategyName, strategies[strategyName]);
 }
      };
      //添加验证策略函数
      //参数:
      // name: 策略名称
      // strategy: 策略函数
      InputValidators.prototype.addValidationStrategy = function(name, strategy){
 this.strategies[name] = strategy;
      };

步骤3:

添加验证方法,接受外部调用。

第一个参数rule,设置成验证规则,比如 "minLength:6",通过下面的代码会生成对具体策略函数的调用,调用会压到缓存中,等待一起调用。

":6"表示策略函数根据自身规则所定制的参数。     

  //添加验证方法
      //参数:
      // rule: 验证策略字符串
      // element: 被验证的dom元素
      // errMsg: 验证失败时显示的提示信息
      // value: 被验证的值
      InputValidators.prototype.addValidator = function(rule, element, errMsg, value) {
 var that = this;
 var ruleElements = rule.split(":");
 this.validators.push(function() {
   var strategy = ruleElements.shift();
   var params = ruleElements;
   params.unshift(value);
   params.unshift(errMsg);
   params.unshift(element);
   return that.strategies[strategy].apply(that, params);
 });
      };

通过一个check函数来调用所有的验证。并将错误的结果进行返回。      

   //开始验证
      InputValidators.prototype.check = function() {
 for(var i = 0, validator; validator = this.validators[i++];){
   var result = validator();
   if(result) {
     return result;
   }
 }
      };

步骤4:

在需要验证的地方,先new一个验证器对象。              

var validators = new InputValidators();

将包含验证策略函数的对象导入,或者单独添加验证策略函数。          

  validators.importStrategies(validationStrategies);
 validators.addValidationStrategy('isEqual', function(element, errMsg, value1, value2) {
   if(value1 !== value2) {
     return this.buildInvalidObj(element, errMsg, value1 );
   }
 });

可以看出,不同的验证策略我们可以预先封装进策略对象中,也可以根据实际情况即时添加。

然后通过添加验证方法将需要验证的策略,被验证的dom元素,错误消息,被验证的值添加进验证器中,这样避免了直接调用策略对象,降低了耦合性。

var eleUserName = document.getElementById('userName');
validators.addValidator('isNoEmpty', eleUserName, '用户名不能为空', eleUserName.value);
validators.addValidator('minLength:6', eleUserName, '用户名的字符个数必须是6到20个', eleUserName.value);
validators.addValidator('maxLength:20', eleUserName, '用户名的字符个数必须是6到20个', eleUserName.value);
var elePassword = document.getElementById('password');
validators.addValidator('isNoEmpty', elePassword, '密码不能为空', elePassword.value);
validators.addValidator('minLength:6', elePassword, '密码的字符个数必须是6到20个', elePassword.value);
validators.addValidator('maxLength:20', elePassword, '密码的字符个数必须是6到20个', elePassword.value);
var eleRepassword = document.getElementById('repassword');
validators.addValidator('isNoEmpty', eleRepassword, '确认密码不能为空', eleRepassword.value);
validators.addValidator('minLength:6', eleRepassword, '确认密码的字符个数必须是6到20个', eleRepassword.value);
validators.addValidator('maxLength:20', eleRepassword, '确认密码的字符个数必须是6到20个', eleRepassword.value);
validators.addValidator('isEqual:' + elePassword.value, eleRepassword, '两次密码不一致', eleRepassword.value);
var eleMail = document.getElementById('mail');
validators.addValidator('isNoEmpty', eleMail, '邮箱不能为空', eleMail.value);
validators.addValidator('isMail', eleMail, '邮箱不是一个有效的格式', eleMail.value);

调用验证器的check执行所有的验证。            

var result = validators.check();
 if(result){
   alert(result.errMsg);
   result.element.focus();
   result.element.select();
   return false;
 }

check返回的是错误对象,我们可以在check后通过该对象统一地对DOM元素进行提示性操作,比如设置焦点,选中内容,或者为输入框外部包上一层红色的样式。

至此,可以看出通过策略模式的改在,输入验证时,我们只需要关心用哪个验证规则,采用什么样的提示性信息即可,不再暴露实现细节,方便调用,方便后续的扩展和组件化。

全部代码:



  
    
    
      .form{
 width: 400px;
 height: 200px;
 #margin: 0px auto;
      }
      .form-item-label{
 width:100px;
 text-align: right;
 float: left;
      }
      .form-item-input{
 float: left;
      }
      .form-item{
 width: 100% ;
 height: 50px;
 line-height: 50px;
      }
    
  
  
    
      
 用户名:
 
      
      
 密码:
 
      
      
 确认密码:
 
      
      
 邮箱:
 
      
    
    

以上所述是小编给大家介绍的javascript设计模式--策略模式之输入验证的全部内容,希望大家喜欢。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/99705.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号