两分钟,在前端应用上设计模式!策略模式篇

179 阅读2分钟

前言

本系列会更多的加入自己的思考和观点,可能设计模式并没有书上那么标准,但是会更容易应用到我们的日常工作中。

策略模式

假如有这样一个场景,你提交的表单需要各种验证

一般的想法也就是直接 if 搞定

const checkForm = () => {
    if (userName === '') {
        message.error('name 是必填项');
        return;
    }
    if (age === '') {
        message.error('age 是必填项');
        return;
    }
    if (age < 0) {
        message.error('age 不能小于 0');
        return;
    }
}

但是这样的逻辑并不是很好的解法,当判断条件增多/表单项增多/表单增多,这类代码的数量会直线上升。

我们可以考虑将这些方法抽象一下:

const checkEmpty = (value, errorCallback) => {
    if (value === '') {
        errorCallback();
        return;
    }
}
const checkMinValue = (value, minNumber, errorCallback) => {
    if (value < minNumber) {
        errorCallback();
        return;
    }
}

const checkForm = () => {
    checkEmpty(userName, message.error('name 是必填项'));
    checkEmpty(age, message.error('age 是必填项'));
    checkMinValue(age, 0, message.error('age 不能小于 0'));
}

这么看好了很多,可复用的规则、没有违背开放闭合原则。

不过规则显然是自成一派的函数集,我们可以使用对象将其收拢:

const checkRules = { 
    checkEmpty: (value, errorCallback) => {
        if (value === '') {
            errorCallback();
            return;
        }
    },
    checkMinValue: (value, minNumber, errorCallback) => {
        if (value < minNumber) {
            errorCallback();
            return;
        }
    }
}

好的,你也许没意识到,你已经实现了一个简单的策略模式 🎉 🎉 🎉

策略模式:

特点:将算法的定义与使用分离,减少代码耦合;避免大量的 if 且遵循开放/封闭原则

用途:表单检测、成绩分级、权限系统等

实现:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。 人话版就是将相近的函数抽离到一个公共的组中,根据需要选择使用不同的函数,这就是策略

其他

照旧,再来看一个正经而标准的 es6 策略模式

// 策略集合
const strategies = {
  add: (a, b) => a + b,
  subtract: (a, b) => a - b,
  multiply: (a, b) => a * b,
  divide: (a, b) => a / b,
};

// 环境类
class Calculator {
  constructor(strategy) {
    this.strategy = strategy;
  }

  setStrategy(strategy) {
    this.strategy = strategy;
  }

  calculate(a, b) {
    return this.strategy(a, b);
  }
}

// 使用示例
const calculator = new Calculator(strategies.add);
console.log(calculator.calculate(5, 3)); // 8

calculator.setStrategy(strategies.multiply);
console.log(calculator.calculate(5, 3)); // 15

依旧是在工作中很难应用出来,就像是掌握了屠龙秘籍却找不到龙。

如果这篇文章对你有帮助,不妨点个赞吧~