手把手带你使用策略模式实现表单校验

Posted 前端呆头鹅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手把手带你使用策略模式实现表单校验相关的知识,希望对你有一定的参考价值。

策略模式

文章目录

前言

你的项目有哪些亮点?你对设计模式是否了解?这些都是面试官常问的问题,这两个问题都可以通过本文解决。

毋庸置疑,使用策略模式实现表单校验就是你项目的亮点,也是你掌握设计模式的体现!

一 了解策略模式

很多公司,员工的绩效与年终奖挂钩,假设员工绩效为S时,年终奖为月工资4,员工绩效为A时,年终奖为月工资2。该逻辑代码如下:

var getMonay = function(level, salary) 
  if(level === 'S') 
    return salary * 4
  
  if(level === 'A') 
    return salary * 2
  

console.log(getMonay('S', 1000)) // 4000
console.log(getMonay('A', 1000)) // 2000

策略模式的定义是:定义一系列的算法,将它们封装起来,它们可以相互替换。

策略模式实际上是将算法的使用和算法的实现分离,在算法使用时传入本次使用的算法。感觉有些绕,但是看完这章你就能马上理解。

首先我们将算法的实现和使用分离。

var getMonayS = function(salary) 
  return salary * 4

var getMonayA = function(salary) 
  return salary * 2

var getMonay = function(level, salary) 
  if(level === 'S') 
    return getMonayS(salary)
  
  if(level === 'A') 
    return getMonayA(salary)
  

console.log(getMonay('S', 1000)) // 4000
console.log(getMonay('A', 1000)) // 2000

可以看到在上面的代码中,算法的使用和实现已经分离,其中,getMonay方法为使用函数,getMonayS、getMonayA方法为实现函数。在getMonay方法中根据传入参数的不同调用不同实现函数。

可以看出这样的优化增加了代码复用性,代码也更清晰,但是仍然存在大量if。

策略模式主要由两个类组成:
策略类:封装算法实现 (上文中的getMonayS、getMonayA)
环境类:接受请求 将请求委托给某一个策略类。(上文中的getMonay)

我们将上面的代码以类的方式封装,完全去掉if语句。

var getMonayS = function(salary) 
  return salary * 4

var getMonayA = function(salary) 
  return salary * 2

class getMonay 
  salary = null
  strategy = null
  setSalary(salary) 
    this.salary = salary
  
  setStrategy(strategy) 
    this.strategy = strategy
  
  getBonus() 
    if(!strategy) 
      throw new Error('未设置strategy属性')
    
    return this.strategy(this.salary)
  

var bonusS = new getMonay
bonusS.setStrategy(getMonayS)
bonusS.setSalary(1000)
console.log(bonusS.getBonus())

var bonusA = new getMonay
bonusA.setStrategy(getMonayA)
bonusA.setSalary(1000)
console.log(bonusA.getBonus())

上面的代码实际上就是传入并储存相关变量和策略函数,用来计算结果的思路,JS语言的灵活性让代码可以有更简单的实现方式,去掉代码多余部分,可修改如下。

var getMonay = 
  S(salary) 
    return salary * 4
  ,
  A(salary) 
    return salary * 2
  

var bouns = function(salary, strategy) 
  return getMonay[strategy](salary)

console.log(bouns(1000, 'S'))
console.log(bouns(1000, 'A'))

到此为止,我们实现了一个简单的从充满if-else的代码到策略模式代码的转变,下面我们举一个更为常见的例子,来说明策略模式的用途。

二 实现表单校验

小呆的公司有一段表单校验的代码如下。

var form = 
  userName: '张三',
  password: '0990'

function vaildFun(form) 
  if(form.userName === '') 
    return '用户名不能为空'
  
  if(form.password.length < 6) 
    return '密码长度不能少于6位'
  

console.log(vaildFun(form)) // 密码长度不能少于6位

上面的代码中,类似上文中提到的计算绩效代码,含有多个if语句,我们将其中的逻辑抽象成多个策略函数放在一个对象中。

var strategies = 
  isNonEmpty(value, msg) 
    if(value === '') 
      return msg
    
  ,
  minLength(value, msg) 
    if(value.length < 6) 
      return msg
    
  

现在,我们需要一个方法,可以将Form对象中的value与校验规则联系起来,返回校验结果,使用效果如下。

function vaildFun(form) 
  var validator = new validator
  validator.add('isNonEmpty', form.userName, '用户名不能为空')
  validator.add('minLength:6', form.password, '密码长度不能少于6位')
  console.log(validator.start()) // // 密码长度不能少于6位

现在我们来实现上面代码中使用的validator类,该类中包含一个add方法,可以将Form对象中的value与校验规则联系起来,包含一个start方法,启动校验并返回校验结果。

由于校验信息是在add中存储的,而执行校验是在start中调用的,我们设立一个缓存数组cache来存储校验行为。

class Validator 
  constructor() 
    this.cache = []
  
  add(name, value, msg) 
    this.cache.push(function() 
      return strategies[name](value, msg)
    )
  
  start() 
    for(var i = 0; i < this.cache.length; i ++) 
      var msg = this.cache[i]()
      if(msg) 
        return msg
      
    
  

这样,我们就完成了基于策略模式的表单校验代码优化。

以上是关于手把手带你使用策略模式实现表单校验的主要内容,如果未能解决你的问题,请参考以下文章

手把手带你实现promise源码:培训班小张看后工资暴涨5k

策略模式在表单验证中的应用

javascript设计模式与开发实践阅读笔记——策略模式

js设计模式---策略模式

如何用Python实现股票量化交易?

手把手带你撸一个网易云音乐首页(下篇)