返回总目录


4 Replace Temp with Query(以查询取代临时变量)

概要

你的程序以一个临时变量保存某一表达式的运算结果。

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

动机

临时变量的问题在于:只在当前函数可见。如果你在同类的别的地方访问这个变量,你就必须重新写表达式来获取这个变量,这样的话你就会在不经意间让你的函数变得复杂起来。如果将临时变量替换为一个查询,那么同类中所有函数都可以获得这份信息。

所以如果你想要使用Extract Method,那么Replace Temp with Query是必不可少的一个步骤。而我们前面介绍的Inline Temp其实是这个手法的一部分,两者的区别在于Inline Temp已经有了表达式自身,只需要做简单的替换就可以,需要用表达式本身把临时变量给去掉。而Replace Temp with Query更加全面,里面包含了提炼表达式到函数本身,然后替换引用点(Inline Temp)。如果你把所有的临时变量都替换为一个查询,你的类的结构和逻辑将非常清晰,这样将更加有利于你的重构和进行优化。

范例

假设有以下简单函数:

double GetPrice()
{
int basePrice = _quantity * _itemPrice;
double discountFactor;
if (basePrice > )
{
discountFactor = 0.95;
}
else
{
discountFactor = 0.98;
}
return basePrice * discountFactor;
}

我们现在将basePrice 和discountFactor这两个临时变量都替换掉。

先来替换basePrice,将basePrice右侧表达式提炼出来,然后使用Inline Temp将basePrice的所有引用点都替换掉,并且把basePrice临时变量的声明去掉。

现在代码变成这样:

double GetPrice()
{
double discountFactor;
if (GetBasePrice() > )
{
discountFactor = 0.95;
}
else
{
discountFactor = 0.98;
}
return GetBasePrice() * discountFactor;
} private int GetBasePrice()
{
return _quantity * _itemPrice;
}

再以类似的方法提炼出GetDiscountFactor();

private double GetDiscountFactor()
{
if (GetBasePrice() > )
{
return 0.95;
}
return 0.98;
}

最终代码是这样的。

double GetPrice()
{
return GetBasePrice() * GetDiscountFactor();
} private double GetDiscountFactor()
{
if (GetBasePrice() > )
{
return 0.95;
}
return 0.98;
} private int GetBasePrice()
{
return _quantity * _itemPrice;
}

可以明显的看到,这个重构手法对于函数本身来说,提高了清晰度,也让我们进行后期重构能够更加便捷。

小结

我们常常在循环中用临时变量保存累加信息。如果是这种情况的话,我们可以将整个循环都提炼出来。如果在循环中要累加好几个值,那么就应该针对每个累加值重复一遍循环。这样,就可以很方便的将所有临时变量都替换为查询。

当然,这样一来,我们可能担心性能问题。本来我定义一个临时变量只需要查询一次,现在我每次都要去做查询。这个我们完全不必担心。重构的目的是让程序更加清晰,有了更加清晰的程序之后再具体做优化也不迟,况且根据二八原则,仅仅这条查询语句倘若你系统真的出现了性能问题也不大可能,如果实在是因为这条语句,你也可以把变量再放回去。

To Be Continued...

重构手法之Replace Temp with Query(以查询取代临时变量)的更多相关文章

  1. 代码重构与单元测试——使用“以查询取代临时变量”再次对Statement()方法进行重构(七)

    代码重构与单元测试(一) 代码重构与单元测试--测试项目(二) 代码重构与单元测试--"提取方法"重构(三) 代码重构与单元测试--重构1的单元测试(四) 代码重构与单元测试--对 ...

  2. 重构改善既有代码设计--重构手法04:Replace Temp with Query (以查询取代临时变量)

    所谓的以查询取代临时变量:就是当你的程序以一个临时变量保存某一个表达式的运算效果.将这个表达式提炼到一个独立函数中.将这个临时变量的所有引用点替换为对新函数的调用.此后,新函数就可以被其他函数调用. ...

  3. 《重构-改善既有代码的设计》学习笔记---Replace Temp with Query(以查询取代临时变量)

    临时变量的问题在于: 它们是暂时的,而且只能在所属函数内使用.由于临时变量只在所属函数内可见,所以,如果很多地方都在用这个临时变量,就会驱使你写出更长的函数.如果把临时变量替换为一个查询,那么其他函数 ...

  4. 『重构--改善既有代码的设计』读书笔记----Replace Temp with Query

    Replace Temp with Query,顾名思义,表示你用查询来替换临时变量本身,临时变量对于函数来说是只有当前函数可见的,如果你在同类的别的地方要用到这个变量你就必须重新写表达式来获取这个变 ...

  5. 重构代码 —— 函数即变量(Replace temp with Query)

    函数即变量,这里的函数指的是返回值为某一对象的函数.Replace temp with query,query 是一种查询函数. example 1 double price() { return t ...

  6. Replace Temp with Query

    double GetPrice() { int basePrice = _quantity * _itemPrice; double discountFactor; ) { discountFacto ...

  7. 重构改善既有代码设计--重构手法08:Replace Method with Method Object (以函数对象取代函数)

    你有一个大型函数,其中对局部变量的使用,使你无法釆用 Extract Method. 将这个函数放进一个单独对象中,如此一来局部变量就成了对象内的值域(field) 然后你可以在同一个对象中将这个大型 ...

  8. 重构改善既有代码设计--重构手法01:Extract Method (提炼函数)

    背景: 你有一段代码可以被组织在一起并独立出来.将这段代码放进一个独立函数,并让函数名称解释该函数的用途. void PrintOwing(double amount) { PrintBanner() ...

  9. 重构改善既有代码设计--重构手法02:Inline Method (内联函数)& 03: Inline Temp(内联临时变量)

    Inline Method (内联函数) 一个函数调用的本体与名称同样清楚易懂.在函数调用点插入函数体,然后移除该函数. int GetRating() { return MoreThanfiveLa ...

随机推荐

  1. 使用路由延迟加载 Angular 模块

    使用路由延迟加载 Angular 模块 Angular 非常模块化,模块化的一个非常有用的特性就是模块作为延迟加载点.延迟加载意味着可以在后台加载一个模块和其包含的所有组件等资源.这样 Angular ...

  2. python _winreg模块

    详细资料请参考:https://docs.python.org/2/library/_winreg.html 一.常用函数功能介绍 OpenKey() - 打开一个key ############## ...

  3. python urllib、urlparse、urllib2、cookielib

    1.urllib模块 1.urllib.urlopen(url[,data[,proxies]]) 打开一个url的方法,返回一个文件对象,然后可以进行类似文件对象的操作.本例试着打开google i ...

  4. 搭建git远程服务器三步骤

    以前都是使用git,这次由于工作需要,需要自己搭建一个远程git服务器.根据网上的 介绍,捣鼓了一下午,终于把远程git服务器搞定了,这里,做个总结. 搭建git远程服务,首先要安装git和ssh,以 ...

  5. Jquery+Ajax限制查询间隔

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Jquery20150305.a ...

  6. 【学习】原生js学习笔记1:添加class和使input为不可用

    <input type="checkbox" id="new_check" onChange="noUse()" checked> ...

  7. vue-cli 自定义指令directive 添加验证滑块

    vue项目注册登录页面遇到了一个需要滑块的功能,网上看了很多插件发现都不太好用,于是自己写了一个插件供大家参考: 用的是vue的自定义指令direcive,只需要在需要的组件里放入对应的标签嵌套即可: ...

  8. JS 巧用 && 与 ||

    在对于流程控制语句当中,我们最熟悉不过的就是 if (条件){ //代码块 }else{ //代码块 } 对于一个执行不同的代码来说,如果执行的代码很多,可能就有必要使用上面这种方式 但往往我们开发当 ...

  9. 关于 SVN 项目检出

    前几天呢,同事遇到这么一个问题:他新建了一个工作空间,当他通过 svn 检出公司项目的时候,准备过来测试运行,但是呢出现了下面的报错 [ERROR] Failed to execute goal or ...

  10. 队列(存储结构数组)--Java实现

    /*队列:其实也是一种操作受限的线性表 *特点:先进先出 *队尾指针:负责元素的进队 *队头指针:负责元素的出队 *注意:普通队--容易浪费空间,一般队列使用最多的就是循环队列--指针环绕 *队列的实 ...