一、什么是分支优化
实际开发工作中,我们经常需要做条件判断
,不同条件执行不同逻辑代码。最常用到的方案是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文件,之后在需要使用的地方导入即可。
注意:策略模式中注意单一职责原则
和开闭原则
的考虑