重构之对象映射类型
写代码的时候,遇到多重条件分支的时候,使用if else if肯定不如 switch 好用,但 switch 又避免不了 break 语句。但如果只是将数据转化的话,不妨使用对象映射的形式来替换
需求
题型对应的数字转化 将单选 0 多选 1 填空 2 判断 3 简答 4 其他类型-1 转化为 单选 1 多选 2 判断 3 填空 4 简答 5 其他类型-1
目的:前者是其他来源的题目题型标记,而后者是存入数据库的题目标记。
代码
if else if 语句
let ti = {
  title: '题目',
  answer: '答案',
  type: null,
};
let type = 0;
if (type === 0) {
  ti.type = 1;
} else if (type === 1) {
  ti.type = 2;
} else if (type === 2) {
  ti.type = 3;
} else if (type === 3) {
  ti.type = 4;
} else if (type === 4) {
  ti.type = 5;
} else {
  ti.type = -1;
}
console.log(ti.type); // 1
swtich 语句
let ti = {
  title: '题目',
  answer: '答案',
  type: null,
};
let type = 0;
switch (type) {
  case 0:
    ti.type = 1;
    break;
  case 1:
    ti.type = 2;
    break;
  case 2:
    ti.type = 3;
    break;
  case 3:
    ti.type = 4;
    break;
  case 4:
    ti.type = 5;
    break;
  default:
    ti.type = -1;
    break;
}
console.log(ti.type); // 1
显而易见 上面的代码写的很臃肿,并且可读性很差,万一这时候有道题型对应数字的发生了改变,就很容易改错。
不妨定义一个对象,用于映射不同的题目题型,像下面这样
let ti = {
  title: '题目',
  answer: '答案',
  type: null,
};
let type = 0;
const typeMap = {
  0: 1, // 单选
  1: 2, // 多选
  2: 3, // 判断
  3: 4, // 填空
  4: 5, // 简答
};
ti.type = typeMap[type] ?? -1; // typeMap[type]为0的话 为假值 使用||将会赋值为-1
console.log(ti.type); // 1
像这样的例子还有状态映射。
let status = 1
const statusMap = {
  0: '未使用'
  1: '已使用',
}
let statusStr = statusMap[status]
这样已经很好了,这里的 1 2 3 4 5 后都添加了注释,增加了一定的可读性,但是还不够,有时候在引用的话或记混了都有可能把填空题判断成简答题,比如后续使用的代码
switch (ti.type) {
  case 1: // 单选
    // ...
    break;
  case 2: // 多选
    // ...
    break;
  case 3: // 判断
    // ...
    break;
  case 4: // 填空
    // ...
    break;
  case 5: // 简答
    // ...
    break;
  default:
    break;
}
又需要加一遍注释,如果不看typeMap的话,就很大的可能会写错。于是一个好的命名就至关重要了
enum(枚举)
如果使用的是 Typescript,那么可以直接使用 enum(枚举)
enum Qtype {
  RADIO = 0,
  MULT = 1,
  BLANK = 2,
  JUDGE = 3,
  SHORT = 4,
  UNKNOWN = -1,
}
此时的整个代码就可以写成这样
let ti = {
  title: '题目',
  answer: '答案',
  type: null,
};
let type = 0;
const typeMap = {
  0: Qtype.RADIO, // 单选
  1: Qtype.CHECK, // 多选
  2: Qtype.JUDGE, // 判断
  3: Qtype.BLANK, // 填空
  4: Qtype.SHORT, // 简答
};
ti.type = typeMap[type] ?? Qtype.UNKNOWN;
console.log(ti.type); // 1
switch (ti.type) {
  case Qtype.RADIO:
    // ...
    break;
  case Qtype.CHECK: // 多选
    // ...
    break;
  case Qtype.JUDGE: // 判断
    // ...
    break;
  case Qtype.BLANK: // 填空
    // ...
    break;
  case Qtype.SHORT: // 简答
    // ...
    break;
  default:
    break;
}
如果不新建一个typeMap变量,还可以直接这样操作
ti.type = {
  0: Qtype.RADIO, // 单选
  1: Qtype.CHECK, // 多选
  2: Qtype.JUDGE, // 判断
  3: Qtype.BLANK, // 填空
  4: Qtype.SHORT, // 简答
}[type] ?? Qtype.UNKNOWN;
后续重构
如果这时候需求发生了变化,比如判断题与填空题的数字要交换一下,那么也只需要修改Qtype,极大的提高了开发的效率与 bug 的发生。