本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/42386305
在上一篇文章中介绍了“ 内联临时变量“。本文将介绍“以查询取代临时变量”这种重构手法。
下面让我们来学习这种重构手法吧。
开门见山
发现:你的程序以一个临时变量保存某一表达式的运算结果。
解决:将这个表达式提炼到一个独立函数中。将这个临时变量的所有引用点替换为对新函数的调用。
//重构前
double basePrice = _quantity * _itemPrice;
if(basePrice > 5000)
return basePrice * 0.95;
else
return basePrice * 0.98;
//重构后
if(basePrice() > 5000)
return basePrice() * 0.95;
else
return basePrice() * 0.98;
...
double basePrice(){
return _quantity * _itemPrice;
}
动机
我们都知道临时变量都是暂时的,而且只能在所属的函数中使用。所以它们会驱使你写出更长的函数,因为只有这样你才能访问到需要的临时变量。如果把临时变量替换为一个查询,那么同一个类中所有函数都将可以获得这份信息。这将带给你极大帮助,使你能够为这个类编写出更清晰的代码。
该重构方法往往是你运用提炼函数之前必不可少的一个步骤。局部变量会使得代码难以提炼,所以应该尽可能把它们替换为查询式。比较简单的情况是:临时变量只被赋值一次,或者赋值给临时变量的表达式不受其它条件影响。
做法
我们常常使用临时变量保存循环中的累加信息。在这种情况下,整个循环都可以被提炼为一个独立的函数,这可以减少原函数中几行循环逻辑代码。该手法的使用可能会让你担心性能上的问题。就像和其它性能问题一样,我们现在不用管它,因为十有八九根本没有造成任何影响。就算真的出问题了,你也可以在优化时期解决它。代码组织良好,你也会发现更有效的优化方案;如果没有进行重构,好的优化方案就可能与你失之交臂。
示例
//重构前
double getPrice() {
int basePrice = _quantity * _itemPrice;
double discountFactor;
if (basePrice > 5000)
discountFactor = 0.95;
else
discountFactor = 0.98;
return basePrice * discountFactor;
}
我们希望将其中的两个临时变量都去掉。当然,每次一个进行处理。
double getPrice() {
final int basePrice = _quantity * _itemPrice;
final double discountFactor;
if (basePrice > 5000)
discountFactor = 0.95;
else
discountFactor = 0.98;
return basePrice * discountFactor;
}
这样,一旦有问题编译器就会警告。之所以需要这个做是因为如果临时不安路口不只被赋值一次,就不该进行这项重构。
double getPrice() {
final int basePrice = basePrice();
final double discountFactor;
if (basePrice > 5000)
discountFactor = 0.95;
else
discountFactor = 0.98;
return basePrice * discountFactor;
}
private double basePrice() {
return _quantity * _itemPrice;
}
然后,编译并测试,再开始使用内联临时变量。
double getPrice() {
final int basePrice = basePrice();
final double discountFactor;
if (basePrice() > 5000)
discountFactor = 0.95;
else
discountFactor = 0.98;
return basePrice * discountFactor;
}
编译、测试,然后进行下一个。由于下一个是最后一个引用点,所以把basePrice临时变量的声明式一并去掉:
double getPrice() {
final double discountFactor;
if (basePrice() > 5000)
discountFactor = 0.95;
else
discountFactor = 0.98;
return basePrice() * discountFactor;
}
完成basePrice之后,以类似的方法提炼出discountFactor():
double getPrice() {
final double discountFactor = discountFactor() ;
return basePrice() * discountFactor;
}
private double discountFactor(){
if (basePrice() > 5000)
return 0.95;
else
return 0.98;
}
你会发现,如果没有把临时变量basePrice替换为一个查询式,将多么难以提炼discountFactor()!
//重构后
double getPrice() {
return basePrice() * discountFactor();
}
重构笔记文章如下