返回总目录

本小节目录

6 Split Temporary Variable(分解临时变量)

概要

你的程序有某个临时变量被赋值超过一次,它既不是循环变量,也不被用于收集计算结果。

针对每次赋值,创造一个独立、对应的临时变量。

动机

临时变量有各种不同的用途。

1、循环变量;

2、结果收集变量;

3、保存一段冗长代码的运算结果,便于稍后使用。

其中第三种情况的临时变量应该只被赋值一次。如果它们被赋值超过一次,就意味着它们在函数中承担了一个以上的责任。如果临时变量承担了多个责任,它就应该被分解为多个临时变量,每个变量只承担一个责任。同一个临时变量承担两件不同的事情,会令代码阅读者糊涂。

范例

double GetTotalCost()
{
double result = ; double money = _chickMoney + _chipMoney; result += money; money = _cocoaMoney + _coffeeMoney; result += money; return result;
}

可以看到在这个范例中,临时变量money被赋值两次。并且它没有做到累积结果的作用,累积结果给了result。所以,我们需要做重构,让这个变量的意图变的更加明确。

所以我们第一步,寻找这个变量第一次声明的地方,并且将他改名,然后修改在第二次赋值之前的所有引用点,并且在第二次赋值处进行重新声明:

double GetTotalCost()
{
double result = ; double mealMoney = _chickMoney + _chipMoney; result += mealMoney ; double money = _cocoaMoney + _coffeeMoney; result += money; return result;
}

现在,新的临时变量只承担原先money的第一个责任。而且我们在原先money变量第二次被赋值处重新声明了money。然后,继续处理money临时变量的第二次赋值。

double GetTotalCost()
{
double result = ; double mealMoney = _chickMoney + _chipMoney; result += mealMoney ; double drinkMoney = _cocoaMoney + _coffeeMoney; result += drinkMoney ; return result;
}

可以看到,我们完成了变量的重构之后,函数对于临时变量之前的money的困惑已经没有了,整体因为变量名字的本身使得逻辑更加清晰。

如果在这里你的代码还是比较复杂的话,可以尽情使用其他的重构手法。

小结

这个重构手法的重点在于:临时变量不是用于循环变量和结果收集,但却被赋值超过两次,那就对它进行分解,使其每次只承担一个责任。

7 Remove Assignments to Parameters(移除对参数的赋值)

概要

代码对一个参数进行赋值。

以一个临时变量取代该参数的位置。

动机

首先要明确这里“对参数赋值”的意思。如果你把一个名为foo的对象作为参数传给某个函数,那么“对参数赋值”就意味着改变foo,使它引用另一个对象。如果在“被传入对象”身上进行什么操作,那是没问题的。Java只采用按值传递的方式,而C#分为值传递和引用传递,关于C#的值传递和引用传递,请看我的另一篇文章,或者自行百度。

int test(int a)
{
if (a > )
{
a = ;
}
return a;
}

这个就违反了这个原则,因为你对传入参数进行重新赋值会让代码阅读者产生歧义,降低了代码的清晰度。他们搞不清甚至看不懂你参数到底代表什么含义,甚至会对你这个参数的稳定性表示担忧。

在值类型按值传递的情况下,对参数的任何修改,都不会对调用端造成任何影响。这个重构手法也是针对值类型按值传递的。

范例

int GetDiscount(int inputVal, int quantity, int yearToDate)
{
if (inputVal > )
{
inputVal -= ;
}
if (quantity > )
{
inputVal -= ;
}
if (yearToDate > )
{
inputVal -= ;
}
return inputVal;
}

以临时变量取代对参数的赋值动作,得到以下代码:

int GetDiscount(int inputVal, int quantity, int yearToDate)
{
int result=inputVal;
if (inputVal > )
{
result-= ;
}
if (quantity > )
{
result-= ;
}
if (yearToDate > )
{
result-= ;
}
return result;
}

小结

如果参数只表示“被传递进来的东西”,那么代码会很清晰。

To Be Continued...

重构手法之Split Temporary Variable(分解临时变量)的更多相关文章

  1. 『重构--改善既有代码的设计』读书笔记----Split Temporary Variable

    继续开始我们重构手法的系列,今天介绍的是Split Temporary Variable---分解临时变量. 在我们平常写的程序中肯定有某些临时变量被赋予了超过一个的责任.如果他们不是那种收集结果(t ...

  2. 重构改善既有代码设计--重构手法06:Split Temporary Variable (分解临时变量)

    你的程序有某个临时变量被赋值超过一次,它既不是循环变量,也不被用于收集计算结果.针对每次赋值,创造一个独立.对应的临时变量 double temp = 2 * (_height + _width); ...

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

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

  4. 重构手法之Introduce Explaining Variable(引用解释性变量)

    返回总目录 6.5Introduce Explaining Variable(引用解释性变量) 概要 你有一个复杂的表达式. 将该复杂表达式(或其中一部分)的结果放进一个临时变量,以此变量名称来解释表 ...

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

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

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

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

  7. 重构改善既有代码设计--重构手法05:Introduce Explaining Variable (引入解释性变量)

      发现:你有一个复杂的表达式. 解决:将该复杂的表达式(或其中的部分)的结果放进一个临时变量,并以此变量名称来解释表达式用途. //重构前 if((platform.toUpperCase().in ...

  8. 重构手法之Replace Temp with Query(以查询取代临时变量)

    返回总目录 6.4Replace Temp with Query(以查询取代临时变量) 概要 你的程序以一个临时变量保存某一表达式的运算结果. 将这个表达式提炼到一个独立函数中.将这个临时变量的所有引 ...

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

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

随机推荐

  1. redis的sentinel主从切换(failover)与Jedis线程池自动重连

    本文介绍如何通过sentinel监控redis主从集群,并通过jedis自动切换ip和端口. 1.配置redis主从实例 10.93.21.21:6379 10.93.21.21:6389 10.93 ...

  2. Linux用户角色划分

    在Linux系统中,用户是分角色的,角色不同,对应权限不同.用户角色通过UID和GID识别. 大致分为三种:超级用户,普通用户,虚拟用户. 超级用户:默认是root用户,其UID和GID都是0.roo ...

  3. Echarts数据可视化parallel平行坐标系,开发全解+完美注释

    全栈工程师开发手册 (作者:栾鹏) Echarts数据可视化开发代码注释全解 Echarts数据可视化开发参数配置全解 6大公共组件详解(点击进入): title详解. tooltip详解.toolb ...

  4. jquery层次选择器:空格 > next + nextAll ~ siblings

    全栈工程师开发手册 (作者:栾鹏) jquery系列教程1-选择器全解 jquery层次选择器 jquery层次选择器,包括空格.>.next.+.nextAll.~.siblings等函数或表 ...

  5. OC实现同步访问属性

    有时候,我们在开发过程中需要对属性的访问进行同步操作,这种属性需要做成原子的,用atomic来修饰属性,即可实现这一点. 如果我们想自己实现,可以按照下面方式写代码: SFPerson.h #impo ...

  6. eclipse环境下,java操作MySQL的简单演示

    首先先通过power shell 进入MySQL 查看现在数据库的状态(博主是win10系统) 右键开始,选择Windows powershell ,输入MySQL -u用户名 -p密码 选择数据库( ...

  7. Python学习常用的好网站

    以下总结出自己在学习python期间常用的网址或者资源,其中包括很多人的博客,方便自己从这个入口查找资源. 1.https://www.liaoxuefeng.com/wiki/00143160895 ...

  8. java如何调用接口方式二

    java如何调用接口 在实际开发过程中,我们经常需要调用对方提供的接口或测试自己写的接口是否合适,所以,问题来了,java如何调用接口?很多项目都会封装规定好本身项目的接口规范,所以大多数需要去调用对 ...

  9. Spring 笔记总结

    1.Spring框架的核心是提供一个容器(BeanFactory 或 ApplicationContext),提供以下功能: 1)创建和销毁组件对象,类似"工厂类" 2)采用不同的 ...

  10. 有关Datatabled的合并,排序和删除重复行的方法

    当某些操作需要涉及合并Datatable时,我们应该如何操作呢? 下面是自己总结的一些方法: 当有两表dt1和dt2的时候,使用dt1.Merge(dt2) 可以将表1表2中相同的合并在一起 排序方法 ...