函数中的条件逻辑使人难以看清正常的执行路径

function getPayAmount () {
  let result
  if (isDead) result = deadAmount()
  else {
    if (isSeparated) result = separatedAmount()
    else {
      if (isRetired) result = retiredAmount()
      else result = normalPayAmount()
    }
  }
  return result
}

改造后:

function getPayAmount () {
  if (isDead) return deadAmount()
  if (isSeparated) return separatedAmount()
  if (isRetired) return retiredAmount()
  return normalPayAmount()
}

动机

  条件表达式通常有两种表现形式。一种是:所有分支都属于正常行为。另外一种是:条件表达式提供的答案只有一个是正常行为,其他都是不常见的情况。

  这两类条件表达式有不同的用途,这一点应该通过代码表现出来。如果两条分支都是正常行为,就应该使用if...else...的条件表达式;如果某个条件极为罕见,就应该单独检查该条件,并在该条件为真时理科从函数中返回。这样的单独检查常常被称为“卫语句(guard clauses)[Beck]”。

  卫语句取代嵌套表达式的精髓就是:给某一条分支以特别的重视。如果使用if-then-else结构,你对if分支和else分支的重视是同等的。这样的代码结构传递给阅读者的消息就是:各个分支有同样的重要性。卫语句就不同,他告诉阅读者:“这种情况很罕见,如果他真地发生了,请做一些必要的整理工作,然后退出。”

做法

  • 对于每个检查,放进一个卫语句。(卫语句要不就从函数返回,要不就抛出一个异常)

范例:条件反转

有时候可以还可以将条件表达式进行反转:

function getAdjustedCapital () {
  let result = 0
  if (captial > 0) {
    if (intRate > 0 && duration > 0) {
      result = (income / duration) * ADJ_FACTOR
    } 
  }
  return result
}

改造后:

function getAdjustedCapital () {
  if (captial <= 0) return 0
  if (intRate <= 0 || duration <= 0) return 0
  return (income / duration) * ADJ_FACTOR
}

声明

以上摘抄自《重构改善既有代码的设计》一书,代码部分由原来的java改写成javascript。目的仅为加深印象和理解,如有侵权请联系。