JS策略模式优雅地处理复杂的条件判断

一、背景

在前端开发中,我们经常会遇到比较复杂的条件判断,普遍的做法都是 if / else,但是当项目中出现过多的条件判断的时候,会使得我们的代码臃肿而变得难以维护和理解;优雅一点的写法是我们会使用switch...case;本文我们结合javascript的策略模式来谈一谈如何优雅地解决代码中带有众多条件判断的情况。

二、策略模式

什么是策略模式?

  • 定义:根据不同参数可以命中不同的策略
  • 主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
  • 何时使用:有许多种情况,而区分它们的只是他们直接的行为。
  • 如何解决:通过一个hash对象,来映射不同的策略。
  • 优点:1、算法可以自由切换。2、避免使用多重条件判断。3、扩展性、复用性良好。
  • 缺点:1、策略类会增多。2、所有策略类都需要对外暴露。
  • 使用场景:1.需要动态地根据行为改变运行方法。2.为了减少代码,同时为了让代码具有更好的可读性。3.需要对策略进行统一管理。

JavaScript中的策略模式

观察如下获取年终奖的 demo,根据不同的参数(level)获得不同策略方法(规则),这是策略模式在 JS 比较经典的运用之一

const strategy = {
  'S1': function(salary) {
    return salary * 4
  },
  'S2': function(salary) {
    return salary * 3
  },
  'S3': function(salary) {
    return salary * 2
  }
}

const calculateBonus = function(level, salary) {
  return strategy[level](salary)
}

calculateBonus('S2', 10000) // 30000

在函数是一等公民的 JS 中,策略模式的使用常常隐藏在高阶函数中,稍微变换下上述 demo 的形式如下,可以发现我们平时已经在使用它了,恭喜我们又掌握了一种设计模式

const S1 = function(salary) {
  return salary * 4
}
const S2 = function(salary) {
  return salary * 3
}
const S3 = function(salary) {
  return salary * 2
}
const calculateBonus = function(func, salary) {
  return func(salary)
}
calculateBonus(S1, 10000) // 40000

三、实际应用

首先我们来看一下实际需求,status(test1和test2两种状态),每种状态下都对应有6种不同的处理情况,(实际应用中可能会有更多)如下:

function func(states, status) {
if(status == 'test1') {
    if(states === 1) {
      // function A()
    } else if (states === 2) {
      // function B()
    } else if (states === 3) {
      // function C()
    } else if (states === 4) {
      // function D()
    } else if (states === 5) {
      // function E()
    } else {
      // function F()
    }
  } else if(status == 'test2') {
    if(states === 1) {
      // function a()
    } else if (states === 2) {
      // function b()
    } else if (states === 3) {
      // function c()
    } else if (states === 4) {
      // function d()
    } else if (states === 5) {
      // function e()
    } else {
      // function f()
    }
  }

通过学习了JS得策略模式,再结合ES6的Map数据结构;上述代码可以经过一下改造:

const exampMap  =  new Map ([
  [{status: 'test1', states: 1}, function A()],
  [{status: 'test1', states: 2}, function B()],
  [{status: 'test1', states: 3}, function C()],
  [{status: 'test2', states: 1}, function a()],
  [{status: 'test2', states: 2}, function b()],
  [{status: 'test2', states: 3}, function c()],
])

const mapHandler = (states, status) {
  let action = [...exampMap].filter(([key, value]) => {key.status === status && key.states === states})
  action.forEach(([key, value]) => {value.call(this)})
}

四、总结

其实javascript的设计模式随处就展示在平常的代码当中,只是我们没有意识到这就是JS的设计模式,通过实际的应用理解掌握才是最有效的。通过策略模式优化众多if/else条件判断的情况,使得代码逻辑清晰,维护性强!在不同的策略下使用不同的匹配方式,例如以上几个states和status对应同一种函数的情况,我们可以借助正则匹配来匹配不同的情况。

你可能感兴趣的:(JS策略模式优雅地处理复杂的条件判断)