if-else 优化方案

524 阅读5分钟

前言

在众多代码中,if-else是最常见的代码语句之一了,这里讲述的是if-else的代码优化方案

实现方案

  • switch 语句优化
  • 三目运算符
  • 对象代理策略
  • 映射关系
  • 条件映射关系方式

实现方案

1)switch 语句优化/三目运算符/对象代理策略/映射关系,实现代码如下

/* *************  type为数字 ************* */

/**
 * @description: 传统的if-else方法
 * @param {*} type
 * @return {*}
 */
function ifelseFun(type) {
    if (type === 1) {
      console.log("执行1方法");
    } else if (type === 2) {
      console.log("执行2方法");
    } else if (type === 3) {
      console.log("执行3方法");
    } else {
      console.log("返回默认值");
    }
  }
  
  /**
   * @description: 三目运算符实现
   * @param {*} type
   * @return {*}
   */
  function ternaryOperatorFun(type) {
    return type === 1
      ? console.log("执行1方法")
      : type === 2
      ? console.log("执行2方法")
      : type === 3
      ? console.log("执行3方法")
      : console.log("返回默认值");
  }
  
  /**
   * @description: switch 方法
   * @param {*} type
   * @return {*}
   */
  function switchFun(type) {
    switch (type) {
      case 1:
        console.log("执行1方法");
        break;
      case 2:
        console.log("执行2方法");
        break;
      case 3:
        console.log("执行3方法");
        break;
      default:
        console.log("返回默认值");
        break;
    }
  }
  
  /**
   * @description: 对象代理策略模式
   * @param {*} type
   * @return {*}
   *
   * 因为上方是数字,可以采用数组
   */
  function arrStrategyFun(type) {
    const ind = type - 1;
    // 策略数组
    const strategyArr = ["执行1方法", "执行2方法", "执行3方法"];
  
    if (strategyArr[ind]) {
      console.log(strategyArr[ind]);
    } else {
      console.log("返回默认值");
    }
  }
  
  /**
   * @description: 对象代理策略模式
   * @param {*} type
   * @return {*}
   */
  function obStrategyFun(type) {
    const obj = {
      1: "执行1方法",
      2: "执行2方法",
      3: "执行3方法",
    };
    if (obj[type]) {
      console.log(obj[type]);
    } else {
      console.log("返回默认值");
    }
  }
  
  console.group("第一类=====>");
  ifelseFun(1);
  ternaryOperatorFun(1);
  switchFun(1);
  arrStrategyFun(1);
  obStrategyFun(1)
  
  ifelseFun(4);
  ternaryOperatorFun(4);
  switchFun(4);
  arrStrategyFun(4);
  obStrategyFun(4)
  console.groupEnd();
  
  /* *************  type为字符串,传统的if-else方法 / 三目运算符 / switch 方法 不做过多讲解 ************* */
  
  /**
   * @description: 对象代理策略模式, 键为字符串,键值为字符串
   * @param {*} type 'first' | 'second' | 'third'
   * @return {*}
   */
  function objStrategyFun(type) {
    const obj = {
      first: "执行1方法",
      second: "执行2方法",
      third: "执行3方法",
    };
  
    return obj[type] || "返回默认值";
  }
  
  console.group("第二类=====>");
  console.log(objStrategyFun("first"));
  console.log(objStrategyFun("third"));
  console.log(objStrategyFun("fourth"));
  
  /**
   * @description: 对象代理策略模式, 键为字符串,键值为方法
   * @param {*} type 'first' | 'second' | 'third'
   * @return {*}
   */
  function objStrategyFun1(type) {
    const obj = {
      first: () => "执行1方法",
      second: () => "执行2方法",
      third: () => "执行3方法",
    };
  
    return obj[type]?.() || "返回默认值";
  }
  
  console.log(objStrategyFun1("first"));
  console.log(objStrategyFun1("third"));
  console.log(objStrategyFun1("fourth"));
  console.groupEnd();
  
  /* *************  type为条件时,请看下方的优化理解 ************* */

控制台打印结果为:

Image.png

各自区别:

  • if-else :  if判断需要使用表达式
  • switch 语句 : case不能使用表达式,只接受字符串/数字;case代码块中不建议过多表达式语句
  • 三目运算符: 作为 if-else 的简洁的运算符
  • 对象代理策略方式 : 其实可以看成是switch 语句的简洁表达方式

场景用途:

  • if-else:符合所有业务场景,业务代码分割
  • switch:业务代码分割
  • 三目运算符:业务代码分割/Vue的插值表达式/React函数组件
  • 对象代理策略:业务代码分割

2)条件映射关系方式

代码示例为:

const oncePriceList = ["一口价"];

/**
 * @description: 正常通过if-else的方式来实现【前提是开启引擎】
 * @param {*} billingMethod 方式
 * @param {*} supplierType 承运商类型
 * @return {*}
 */
function getLadderTypeList(billingMethod, supplierType) {
    if (billingMethod) {
        const ele = billingMethod;
        const commonObj = (ele) => {
            if (!oncePriceList.includes(ele)) {
                if (
                    [
                        "重量",
                        "体积",
                        "件数",
                        "吨公里",
                        "立方公里",
                    ].includes(ele)
                ) {
                    return {
                        list: ["范围阶梯", "累加阶梯", "无阶梯"],
                        value: "范围阶梯",
                    };
                } else if (
                    ["距离", "距离&途经点", "车长&车型"].includes(ele)
                ) {
                    return {
                        list: ["无阶梯"],
                        value: "无阶梯",
                    };
                } else if (
                    [
                        "重量&体积",
                        "重量&件数",
                        "立方公里&途经点",
                        "吨公里&途经点",
                        "吨公里&立方公里",
                        "体积&件数",
                    ].includes(ele)
                ) {
                    return {
                        list: ["范围阶梯", "累加阶梯"],
                        value: "范围阶梯",
                    };
                } else {
                    return {
                        list: [],
                        value: "",
                    };
                }
            } else {
                return {
                    list: [],
                    value: "",
                };
            }
        };
        // 不含承运商类型限制
        if (!supplierType) {
            return commonObj(ele);
        } else {
            if (["承运商", "车队"].includes(supplierType)) {
                if (
                    [
                        "吨公里&立方公里",
                        "吨公里&途经点",
                        "立方公里&途经点",
                    ].includes(ele)
                ) {
                    return {
                        list: [],
                        value: "",
                    };
                } else {
                    return commonObj(ele);
                }
            } else {
                return commonObj(ele);
            }
        }
    } else {
        return {
            list: [],
            value: "",
        };
    }
}

/**
 * @description: 代码优化,实现方式二。使用映射关系来实现
 * @param {*} billingMethod 方式
 * @param {*} supplierType 承运商类型
 * @return {*}
 */
function getNewLadderTypeList(billingMethod, supplierType) {
    const defaultValue = {
        list: [],
        value: "",
    };
    if (billingMethod) {
        // 公共校验函数
        const commonVlidateFun = (item) => {
            // 数组映射关系, 二维数组,元素数组中的第一个元素为检测条件,第二个元素满足条件返回结果
            // 优点,简化if-else代码,逻辑清晰
            // 缺点,编码风格严谨,条件需要排优先级,因为时find方法寻找,不可避免找到多个条件,为了满足唯一一条,所以需要条件优先级先定好方可实现
            const mapList = [
                [
                    ["承运商", "车队"].includes(supplierType) &&
                    [
                        "吨公里&立方公里",
                        "吨公里&途经点",
                        "立方公里&途经点",
                    ].includes(item),
                    defaultValue,
                ],
                [
                    [
                        "重量",
                        "体积",
                        "件数",
                        "吨公里",
                        "立方公里",
                    ].includes(item),
                    {
                        list: ["范围阶梯", "累加阶梯", "无阶梯"],
                        value: "范围阶梯",
                    },
                ],
                [
                    ["距离", "距离&途经点", "车长&车型"].includes(item),
                    {
                        list: ["无阶梯"],
                        value: "无阶梯",
                    },
                ],
                [
                    [
                        "重量&体积",
                        "重量&件数",
                        "立方公里&途经点",
                        "吨公里&途经点",
                        "吨公里&立方公里",
                        "体积&件数",
                    ].includes(item),
                    {
                        list: ["范围阶梯", "累加阶梯"],
                        value: "范围阶梯",
                    },
                ],
            ];

            const validateItem = mapList.find((ele) => ele[0]);
            if (validateItem) {
                return validateItem[1];
            } else {
                return defaultValue;
            }
        };
        return commonVlidateFun(billingMethod);
    } else {
        return defaultValue;
    }
}

console.log(getLadderTypeList("重量"));
console.log(getNewLadderTypeList("重量"));

console.log(getLadderTypeList("立方公里&途经点"));
console.log(getNewLadderTypeList("立方公里&途经点"));

console.log(getLadderTypeList("立方公里&途经点", "承运商"));
console.log(getNewLadderTypeList("立方公里&途经点", "承运商"));


效果为:

image.png

【注意】这里的条件映射关系,是因为对象代理策略的键,只能够接收字符串或数字,不接受表达式。针对条件的优先级排序,这些需要开发者知道条件的优先级等级方可使用。

其实这种方式,无非就是将【对象代理策略方式】中的键值弄成了表达式,Object.entires(obj) 生成的数组元素中是由key 和 value 组成,第一个元素,使用key为表达式,第二,第三...元素作为表达式成功返回的值

总结

if-else / switch 还是最原始,最可靠的代码逻辑分割的产物,但是随着业务代码和逻辑越来越复杂,代码量越来越大,对于通用函数/通用业务使用if-else / switch代码不能够实现良好的可阅读,可维护,不能够让后续开发者在此基础上迭代开发。所以存在上述各种各样的优化方式

当然上述,需要开发者根据相应的场景需要使用,效果更佳

完结撒花...