美文网首页
重新组织函数-Replace Temp With Query(以

重新组织函数-Replace Temp With Query(以

作者: 瑾然有昫 | 来源:发表于2019-12-18 15:35 被阅读0次

一个临时变量保存某一个表达式的运算结果.将这个表达式提炼到一个独立函数中,将这个临时变量的所有引用点替换为对新函数的调用.此后新函数就可以被其他函数调用

示例:

修改前:

$basePrice = $this->quantity * $this->itemPrice;
if ($basePrice > 1000) {
  return $basePrice * 0.95;
} else {
  return $basePrice * 0.98;
}

修改后:

 /**
  * 计算价格
  */
  public function basePrice() {
    return $this->quantity * $this->itemPrice;
  }

  if (basePrice() > 1000) {
    return $basePrice * 0.95;
  } else {
    return $basePrice * 0.98;
  }

动机

  1. 临时变量的问题在于:它们是暂时的.而且只能在所属函数内使用.由于临时变量只能在所属函数内可见.他们会驱使你写出更长的函数.因为只有这样你才能访问到需要的临时变量.如果吧临时变量替换为一个查询,那么同一个类中的所有函数都将可以获得这份信息.
  2. Replace Temp With Query往往是你运用Extract Method之前必不可少的一个步骤.局部变量会使代码变得难以提炼,所有你应该尽可能把它们替换成查询式.

做法

  1. 找出只被赋值一次的临时变量.如果一个临时变量被赋值超过一次则应该考虑使用Split Temporary Variable将它分割成多个变量
  2. 确保该临时变量只被赋值一次
  3. 将对该临时变量赋值的语句等号右侧部分提炼到一个独立函数中.
- 首先将函数声明为private,日后更多类需要使用它时,那时放松对它的保护也很容易.
- 去报提炼出来的函数没有任何副作用,也就是说该函数并不修改任何对象内容.如果他有副作用,就对它进行Separate Query From Modifler.
  1. 在该变量身上实时Inline Temp;

通常情况下,我们常常使用临时变量保存循环中的累加信息.在这种情况下.这个恶循环都一个被提炼为一个独立函数,这也是原本的函数少几行循环逻辑,有时你可能在一个循环中累加好几个值,这种情况你应该针对每个累加值重复一遍循环,这样就可以将所有的临时变量都替换为查询.当然,循环应该简单.
运用此写法,你可能会担心性能问题.和其他性能问题一样.我们现在不管他,因为它可能根本不会造成任何影响.若是性能真的除了问题,你也可以在优化时期解决他.如果性能实在糟糕,要把临时变量放回去也是很容易的.

实例

首先从一个简单的函数开始:

/**
  * 获取价格
  */
public function getPrice() {
  $basePrice = $this->quantity * itemPrice;
  $discounterFactor = 0;
  if ($basePrice > 1000) {
    $discounterFactor = 0.95;
  } else {
    $discounterFactor = 0.95;
  }
  return $basePirce * $discounterFactor;
}

我希望把两个临时变量都替换掉.当然每次一个.如果临时变量不止被赋值一次,就不应该进行这项重构.
接下来开始替换变量,每次一个,首先我把赋值动作的右侧表达式提炼出来

/**
  * 获取价格
  */
public function getPrice() {
  $basePrice = $this->basePrice();
  $discounterFactor = 0;
  if ($basePrice > 1000) {
    $discounterFactor = 0.95;
  } else {
    $discounterFactor = 0.95;
  }
  return $basePirce * $discounterFactor;
}

/**
* 获取基础价格
* @return float
*/
private function basePrice() {
  return $this->quantity * $this->itemPrice;
}

接着使用Inline Temp.首先把临时变量basePrice的第一个引用点替换掉:

/**
  * 获取价格
  */
public function getPrice() {
  $discounterFactor = 0;
  if ( $this->basePrice() > 1000) {
    $discounterFactor = 0.95;
  } else {
    $discounterFactor = 0.95;
  }
  return $basePirce() * $discounterFactor;
}

搞定basePrice之后,我再以类似办法提炼出discountFactor():

/**
* 获取基础价格
* @return float
*/
private function basePrice() {
  return $this->quantity * $this->itemPrice;
}

/**
* 获取折扣率
* @return float
*/
private function discountFactor() {
  if ($this->basePrice() > 1000) {
    return 0.95;
  } else {
    retrun 0.98;
  }
}

最终getPrice变成了这样:

/**
  * 获取价格
  */
public function getPrice() {
  return $this->basePrice() * $this->discounterFactor();
}

相关文章

网友评论

      本文标题:重新组织函数-Replace Temp With Query(以

      本文链接:https://www.haomeiwen.com/subject/bddunctx.html