if-else重构优化

引言:javascript

在咱们编程写代码的时候,咱们会用到if-else或者switch-case的条件判断来负责绝大部分代码,可是不合理的使用if-else条件判断会使咱们的程序复杂度大大提高,同时也会使代码的可读性急速降低,后期维护难度也大大提升。如今咱们一块儿来用几种方法重构优化一下。java

正文:编程

A、合理拆解markdown

咱们在符合条件下要执行函数时,当这段函数代码片断至关长,或者该函数是一段大型函数时,在带有复杂逻辑的条件判断中,检查条件的代码和实现功能的代码会让咱们不清楚是要实现什么功能,从而使代码的可读性大大下降。咱们来看一段代码片断:app

toothAppointCancel(res: any) {
  if (TYPE === XXXX || TYPE === YYYY) {
      history.replace({
      pathname: `/appointmentdetail?jdAppointmentId=${res.msg}&type=${TYPE}`,
    });
    } else {
    window.location.reload();
  }
}
复制代码

该代码片断主要实现了若是当前场景符合某些业务线时去作相应的功能实现,然而从代码表现上看,咱们比较难以很快的看出代码所表达的意图。咱们能够将他拆解为多个独立的函数,拆解的函数能够根据功能来命名,并在原修改处调用该独立的函数来清楚表达咱们的意图。函数

image

让咱们实现一下吧:优化

toothAppointCancel(res: any) {
  const isTooth = () => {
    return TYPE === XXXX || TYPE === YYYY;
  };
  const handleToothUpdate = () => {
    history.replace({
    pathname: `/appointmentdetail?jdAppointmentId=${res.msg}&type=${TYPE}`,
  });
  const handleReload = () => {
    window.location.reload();
  };
  isTooth() ? handleToothUpdate() : handleReload();
}
复制代码

B、合并逻辑ui

有这么一种状况,咱们有不少的条件检查,可是执行的功能函数倒是一致的,那么咱们能够用”逻辑与“或者”逻辑或“来把他们合并成一个表达式。若是咱们这些彼此独立的条件判断能够被视为同一次检查的场景时,一次检查的意图明显在可读性上优于屡次的条件检查。咱们来看一段代码片断:url

if (!(staffInfo.patientName && staffInfo.phone)) {
  // doSomething
}
...
if (!(staffInfo.phone && staffInfo.idCardNum)) {
  // doSomething
}

复制代码

image

咱们能够修改成以下:spa

if(!(staffInfo.patientName && staffInfo.phone) || !(staffInfo.phone && staffInfo.idCardNum)){
  // doSomething
} 
复制代码

C、提早退出

当咱们在一个if条件判断里面再次编写一个if判断,而且里面的if条件依赖于外部的if条件时,咱们也能够用”逻辑与“来优化一下这个实现。咱们来看一下这个代码片断:

function handleEvent(event) {
  if (event) {
    const target = event.target;
    if (target) {
      ...
    }
  }
}
复制代码

咱们检查了下对象event是否为真,以及属性target是否可用。咱们能够以下修改:

image

function handleEvent(event) {
  if (!event || !event.target) {
    return;
  }
  ...
}
复制代码

D、return调整逻辑优先级

若是咱们的if-lese嵌套层级过多而且当咱们判断只有一个条件分支是正常的,另外一个是异常状况,若是异常不容易出现时应该单独检查这个异常的条件。咱们能够区分每一层条件的优先级,把优先级高的放在第一层进行判断,优先级低的放在后面判断,这样咱们能够比较容易的分辨出每一层条件的重要性,能够突出逻辑重点。”每个函数都应该只有一个入口和一个出口“观念,咱们也能够用在if-else中用return模拟这种思想。

image

咱们看一个代码片断:

if (!res) {
  if (relativesType === 1) {
    // doSomething
  }else {
    if (formData.sex === 2 && formData.married === 2) {
    // doSomething
  }
}

复制代码

优化后:

function errorMery(){Toast.show('婚姻状态与套餐不符');}
function alreadyMery(){setDialogInfo({
  ...dialogInfo,
  btnType: 1,
  titleText: '舒适提示',
  contText: MARRIED_TEXT,
  isDialogShow: true,
})}
if (!res) return;
if (relativesType === 1) return errorMery();
if (currLabel === 'married') return alreadyMery();

复制代码

E、用多态替换switch场景

咱们在写switch的时候,对于新手来讲忘记写break实在是再普通不过了,就算是老猿忘记写也是时有发生的事情,而这个语法错误在诸多的语法检查器上没有办法检查出来的,由于从语法角度来讲是正确的,但是代码的处理逻辑倒是错误的。Switch尽管对于break很宽容,可是对判断条件很严苛,case后面只能设置常量。还有一种状况是有一个基础逻辑,基于这个基础逻辑又有一些变体,那么咱们能够把基础逻辑放到超类,把各类变体逻辑放到各个子类。基于此,咱们能够用面向对象中多态的特性来优雅的改善这些问题。 咱们来看一段代码片断:

fixAppointToUrl: (obj: any, type: number) => {
  let url = '';
  switch (type) {
    case TYPEA:
      ...
      url = "B_JD_PE_FIX_URL";
      break;
    case TYPEB:
      ...
      url = "BC_TOOTH_FIX_URL";
      break;
    case TYPEC:
      ...
      url = "C_BACTERIN_FIX_URL";
      break;
    case TYPED:
      ...
      url = "B_TOOTH_FIX_URL";
      break;
    default:
      ...
      url = "DEFAULT_FIX_URL";
  }
  return url;
}
repeatAppointToUrl: (obj: any, type: number) => {
   let url = '';
   switch (type) {
   case TYPEA:
      ...
      url = "B_JD_PE_REPEAT_URL";
      break;
   case TYPEB:
      ...
      url = "BC_TOOTH_REPEAT_URL";
      break;
   case TYPEC:
      ...
      url = "C_BACTERIN_REPEAT_URL";
      break;
   case TYPED:
      ...
      url = "B_TOOTH_REPEAT_URL";
      break;
   default:
      ...
      url = "DEFAULT_REPEAT_URL";
   }
   return url; 
}

复制代码

咱们能够建立一个工厂函数返回一个对象实例,而后将条件逻辑函数转移到超类,在子类中建立函数复写超类中条件表达式的函数。

image

优化后:

class HandleUrl {
  get fixUrl(){
    return 'DEFAULT_FIX_URL';
  }
  get repeatUrl(){
    return 'DEFAULT_REPEAT_URL';
  }
}
class TYPEA extends HandleUrl{
   get fixUrl(){
    return 'B_JD_PE_FIX_URL';
   }
   get repeatUrl(){
    return 'B_JD_PE_REPEAT_URL';
   }
}
class TYPEB extends HandleUrl{
   get fixUrl(){
    return 'BC_TOOTH_FIX_URL';
   }
   get repeatUrl(){
    return 'BC_TOOTH_REPEAT_URL';
   }
}
class TYPEC extends HandleUrl{
   get fixUrl(){
    return 'C_BACTERIN_FIX_URL';
   }
   get repeatUrl(){
    return 'C_BACTERIN_REPEAT_URL';
   }
}
class TYPED extends HandleUrl{
   get fixUrl(){
    return 'B_TOOTH_FIX_URL';
   }
   get repeatUrl(){
    return 'B_TOOTH_REPEAT_URL';
   }
}

复制代码

咱们使用时能够建立一个子类对象调用该业务线特定的url链接:

const typed = new TYPED();
console.log(typed.fixUrl)
复制代码

总结:

对于改善优化if-else条件逻辑代码,咱们使用了分解条件来处理复杂的条件表达式,可使用合并条件来清晰的梳理逻辑,可使用return改善嵌套条件逻辑,可使用多态优化switch判断,由此咱们能够在具体使用传统条件逻辑判断的场景以外多了一种功能实现的选择。

相关文章
相关标签/搜索