Javascript 分支优化——if else / switch case/ 简单策略模式/ 复杂二维数组策略模式

一、什么是分支优化

实际开发工作中,我们经常需要做条件判断,不同条件执行不同逻辑代码。最常用到的方案是if else。但根据分支逻辑的复杂度,需要采取不同方案以达到代码优雅效率高的目的,这个过程就叫做分支优化

二、分支优化的常见方式

工作中我们经常需要处理条件判断的逻辑,例如:

function getUserDescribe(name) {
    if (name === "小刘") {
        console.log("刘哥哥");
    } else if (name === "小红") {
        console.log("小红妹妹");
    } else if (name === "陈龙") {
        console.log("大师");
    } else if (name === "李龙") {
        console.log("师傅");
    } else if (name === "大鹏") {
        console.log("恶人");
    } else {
        console.log("此人比较神秘!");
    }
}

如果是简单判断其实还好,就两三种情况,简单的 if else 就能轻松处理。但如果是遇到像上面这种需要处理多个分支的情况,还可以简单的使用 if else 处理吗?答案显然是不可以的。总不能1000个分支就写1000个if else 吧,那维护难度恐怕是地狱级的。

此时就需要做分支优化了,常见方法主要有以下几种:

1、switch case


function getUserDescribe(name) {
  switch (name) {
	  case '小刘':
	    console.log("刘哥哥");
	    break;
	  case '小红':
	    console.log("小红妹妹");
	    break;
	  case '陈龙':
	    console.log("大师");
	    break;
	  case '李龙':
	    console.log("师傅");
	    break;
	  case '大鹏':
	    console.log("恶人");
	    break;
	  default:
	    console.log("此人比较神秘");
	    break;
	}
}

以上这种方法可以处理单一条件的分支判断

但如果遇到复杂一点的条件判断呢,例如需要判断范围,判断真伪等情况,我们该如何处理?此时我们可以再次巧妙利用switch case的判断原理(主值为true时,分支为true即执行),代码如下:


function getUserDescribe(name) {
  switch (true) {
    case name.length > 3:
      console.log("名字太长");
      break;
    case name.length < 2:
      console.log("名字太短");
      break;
    case name[0] === "李" && name !== "李鹏":
      console.log("这是小李");
      break;
    default:
      console.log("此人比较神秘");
      break;
  }
}

2、简单策略模式

利用Object的特性,可实现条件判断函数,示例如下:


function getUserDescribe(name) {
    const describeForNameMap = {
        小刘: () => console.log("刘哥哥"),
        小红: () => console.log("小红妹妹"),
        陈龙: () => console.log("大师"),
        李龙: () => console.log("师傅"),
        大鹏: () => console.log("恶人"),
    };
    describeForNameMap[name] ? describeForNameMap[name]() : console.log("此人比较神秘!");
}

如果代码中的判断都是简单的相等判断,那么我们就可以将这些判断条件作为一个属性写到对象describeForNameMap中去,这些属性对应的值就是条件成立后的处理函数。

之后我们就只需通过getUserDescribe函数接收到的参数去获取describeForNameMap对象中对应的值,如果该值存在就运行该值(因为值是一个函数)。

这样一来原本的 if 分支判断就转换成了简单的key value对应值,条件与处理函数一一对应,一目了然。

3、复杂二维数组策略模式

对于这种结构的代码就不能使用对象来进行分支优化了,我们可以引入二维数组来进行分支优化:

const describeForNameMap = [
    [
        (name) => name.length > 3, // 判断条件
        () => console.log("名字太长") // 执行函数
    ],
    [
        (name) => name.length < 2, 
        () => console.log("名字太短")
    ],
    [
        (name) => name[0] === "陈", 
        () => console.log("小陈")
    ],
    [
        (name) => name === "大鹏", 
        () => console.log("管理员")
    ],
    [
        (name) => name[0] === "李" && name !== "李鹏",
        () => console.log("小李"),
    ],
];
    
function getUserDescribe(name) {
    // 获取符合条件的子数组
    const getDescribe = describeForNameMap.find((item) => item[0](name));
    // 子数组存在则运行子数组中的第二个元素(执行函数)
    getDescribe ? getDescribe[1]() : console.log("此人比较神秘!");
}

此处值得注意的是:对象是一个独立的结构,我们将它抽离到了函数体之外,这样对于后期维护更加友好。

通过模块化的开发也可以将这个map对象写进一个单独的js文件,之后在需要使用的地方导入即可。

注意:策略模式中注意单一职责原则开闭原则的考虑


版权声明:本文为weixin_43936341原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。