首页 > 代码库 > 重构笔记——分解临时变量
重构笔记——分解临时变量
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/42463871
在上一篇文章中介绍了“重构笔记——引入解释性变量“。本文将介绍“分解临时变量”这种重构手法。
下面让我们来学习这种重构手法吧。
开门见山
发现:你的程序有某个临时变量被赋值超过一次,它既不是循环变量,也不被用于收集计算结果。
解决:针对每次赋值,创造一个独立、对应的临时变量。
//重构前 double temp = 2 * (_height + _width); System.out.println(temp); temp = _height + _width; System.out.println(temp);
//重构后 final double perimeter = 2 * (_height + _width); System.out.println(perimeter); final double area = _height + _width; System.out.println(area);
动机
在某些情况下,临时变量用于保存一段冗长代码的运算结果,以便稍后使用。这种临时变量应该只被赋值一次。如果它被赋值超过一次,就意味着它们在函数中承担了一个以上的责任。如果临时变量承担多个责任,它就应该被替换(分解)为多个临时变量,使得每一个变量只承担一个责任。同一个临时变量承担两件不同的事情,会让代码阅读者糊涂。
做法
(1)在待分解临时变量的声明及第一次被赋值处,修改其名称。
(2)将新的临时变量声明为final。
(3)以该临时变量的第二次赋值动作为界,修改此前对该临时变量的所有引用点,让它们引用新的临时变量。
(4)在第二次赋值处,重新声明原先那个临时变量。
(5)编译,测试。
(6)逐次重复上述过程。每次都在声明处对临时变量改名,并修改下次赋值之前的引用点。
示例
我们从一个简单计算开始:我们需要计算一个苏格兰布丁运动的距离。在起点处,静止的布丁会受到一个初始力的作用而开始运动。一段时间后,第二个力作用于布丁,让它再次加速。根据牛顿第二定律,计算布丁运动距离:
double getDistance(int time){ double result; double acc = _primaryForce / _mass; int primaryTime = Math.min(time, _delay); result= 0.5 * acc * primaryTime * primaryTime; int secondaryTime = time - _delay; if(secondaryTime > 0){ double primaryVel = acc *_delay; acc = (_primaryForce + _secondaryForce) / _mass; result += primaryVel * secondaryTime + 0.5 * acc * secondaryTime * secondaryTime; } return result; }代码看起来好像有点丑陋。观察例子中的acc变量是如何被赋值两次。
acc变量有两个责任,一是保存第一个力产生的加速度;二是保存两个力共同产生的加速度。这就是需要分解的东西。
首先,在函数开始修改处修改这个临时变量的名称,并将新的临时变量声明为final。然后,把第二次赋值之前对acc变量的所有引用点,全部改用心的临时变量。最后,在第二次赋值处重新声明acc变量。
double getDistance(int time){ double result; final double primaryAcc = _primaryForce / _mass; int primaryTime = Math.min(time, _delay); result= 0.5 * primaryAcc * primaryTime * primaryTime; int secondaryTime = time - _delay; if(secondaryTime > 0){ double primaryVel = primaryAcc *_delay; double acc = (_primaryForce + _secondaryForce) / _mass; result += primaryVel * secondaryTime + 0.5 * acc * secondaryTime * secondaryTime; } return result; }新的临时变量指出,它只承担原先acc变量的第一个责任。将它声明为final,确保它只被赋值一次。然后,在原先acc变量第二次被赋值处重新声明acc。现在,重新编译并测试,一切都没有问题。
然后继续处理acc临时变量的第二次赋值。
double getDistance(int time){ double result; final double primaryAcc = _primaryForce / _mass; int primaryTime = Math.min(time, _delay); result= 0.5 * primaryAcc * primaryTime * primaryTime; int secondaryTime = time - _delay; if(secondaryTime > 0){ double primaryVel = primaryAcc *_delay; final double secondaryAcc = (_primaryForce + _secondaryForce) / _mass; result += primaryVel * secondaryTime + 0.5 * secondaryAcc * secondaryTime * secondaryTime; } return result; }现在,我想你一定会想到前几篇文章中的一些重构手法,那就尽情使用吧。
//“以查询取代临时变量”手法进行重构 double getDistance(int time){ double result= 0.5 * getPrimaryAcc() * getPrimaryTime(time) * getPrimaryTime(time); if(getSecondaryTime(time) > 0){ result += getSeconddistance(); } return result; } private double getPrimaryAcc(){ return _primaryForce / _mass; } private double getSecondaryAcc(){ return (_primaryForce + _secondaryForce) / _mass; } private int getPrimaryTime(int time){ return Math.min(time, _delay); } private int getSecondaryTime(int time){ return time - _delay; } private double getSeconddistance(){ return getPrimaryAcc() *_delay * getSecondaryTime(time) + 0.5 * getSecondaryAcc() * getSecondaryTime(time) * getSecondaryTime(time); }
本文主要介绍了重构手法——分解临时变量。该重构手法主要针对于变量被赋值多次的情况。一旦函数中的临时变量比较多,且被赋值多次,就比较容易出现问题,阅读代码也很吃力,有必要对其进行调整,让其变得整洁。另外,通过上述示例可以发现,当你在使用一种重构手法的过程中,总是不觉间联想到其它的重构手法,无形中就指引你把代码整理的更好。
最后,希望本文对你有所帮助。有问题可以留言,谢谢。(PS:下一篇将介绍重构笔记——移除对参数的赋值)
重构笔记文章如下
重构笔记——入门篇
重构笔记——代码的坏味道(上)
重构笔记——代码的坏味道(下)
重构笔记——构筑测试体
重构笔记——提炼函数
重构笔记——内联函数
重构笔记——内联临时变量
重构笔记——以查询取代临时变量
重构笔记——引入解释性变量
重构笔记——分解临时变量
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。