重构第六章
3.Inline Temp(内联临时变量)
你有一个临时变量,只被一个简单表达式赋值一次,而它妨碍了其他重构手法
将所有对该变量的引用动作,替换为对它赋值的那个表达式自身
Example:
double basePrice = order.GetBasePrice();
return basePrice > 1000;
Analyze:
书中讲 Inline Temp 低配版时候作为Replace Temp With Query 的一部分使用,真正动机在后者。
唯一单独使用的情况是:某个临时变量被赋予某个函数调用的返回值,同时它阻碍了其他的重构方法。
End:
return order.GetBasePrice() > 1000;
4.Replace Temp with Query(查询取代变量)
你的程序以一个临时变量保存一个表达式的运算结果
将这个表达式封装到一个函数中,将这个临时变量的所有引用点,改为这个函数的调用,新函数可以供其他函数调用
Example:
double basePrice = _quantity * _itemPrice;
if (basePrice>1000) {
return basePrice* 0.95;
} else {
return basePrice*0.98;
}
Analyse
书中讲到,临时变量的问题在于他们是临时的,而且只能在所属函数中使用,所以会导致更长的函数对的出现,把临时变量替换为查询式,可以使得所有函数都可以获得这份信息
情况是:临时变量只赋值为一次,或者赋值给临时变量的表达式不受其他条件影响
思考:这种方法的出现更多的是为了使得函数变得精炼,为其他的重构手法做铺垫
但是实际运行中,要度量一个临时变量的赋值工作是否重复执行,可能表达式的某个变量已经改变;或者有一个循环提炼到一个单独函数中,被重复执行,可能导致时间或者空间上面的重复使用,使得程序的性能降低。
所以在使用这种方法的时候,要在可读性和性能等方面去做权衡,谨慎使用,以免影响到程序的正常使用。
End:
if (basePrice()>1000) {
return basePrice()* 0.95;
} else {
return basePrice()* 0.98;
}
double basePrice() {
return _quantity * _itemPrice;
}
Conclusion:
自我感觉
Inline Temp+Replace Temp with Query 方法进行重构,确实可以使得程序更加的精炼、可读性更加的优越。但是作为一个产品,要在可读性和性能方面进行权衡,灵活使用这两个方法,不要为了使用重构而重构。
引用一句话:什么时候需要重构,需要为程序添加一个特性,但代码结构无法使自己方便的那么做,就先重构那个程序,使得特性添加比较容易
要知道一切的重构手段都是为了程序能够更好地运行,更好的扩展,这些是在不改变程序功能的情况下进行的。
书中实例
重构前:
double getPrice() {
int basePrice = _quatity* _iterPrice;
double discountFactor;
if (basePrice > 1000) {
discountFactor = 0.95;
} else {
discountFactor = 0.98;
}
return basePrice * discountFactor;
}
重构后:
int basePrice() {
return _quatity* _iterPrice;
}
double getDiscountFactor() {
if (basePrice() > 1000) {
return 0.95;
}
else {
return 0.98;
}
}
double getPrice() {
return basePrice() * getDiscountFactor();
}
对于书中的代码最好还是可以码一遍,带着思考去码代码,有时这些代码可能会使你想到你实际项目中的一些代码,可以让你重构的思路不可穷尽
注意
重构必须在有单元测试的情况下,保证之前的功能修改后不收影响。切记!!!
网友评论