你的程序以一个临时变量(temp)保存某一表达式的运算结果。
临时变量会增加函数的长度扩展临时变量生命周期降低提炼函数重构手法难度提炼函数 之前必不可少的一个步骤。局部变量会使代码难以被提炼,所以你应该尽可能把它们替换为查询函数Split Temporary Variable剖解临时变量 将它分割成多个变量。Separate Query from Modifier将查询函数和修改函数分离。下面是一个临时变量的示例代码,通过几个步骤我们使用查询函数替代临时变量重构手法替换掉临时变量。
double getPrice() {int basePrice = _quantity * _itemPrice;double discountFactor;if (basePrice > 1000) discountFactor = 0.95;else discountFactor = 0.98;return basePrice * discountFactor;}
我们希望将示例中两个临时变量都替换掉,但是我们不能一次都替换,要循序渐进。所以我们先替换basePrice
尽管这里的代码十分清楚,我还是先把临时变量声明为final,检查他们是否的确只被赋值一次.
这样一来,如果有任何问题,编译器就会警告我。之所以先做这件事,因为如果临时变量不只被赋值一次,我就不该进行该项重构。
double getPrice() {//将临时变量申明为常量,测试它是否只赋值一次。final int basePrice = _quantity * _itemPrice;final double discountFactor;if (basePrice > 1000) discountFactor = 0.95;else discountFactor = 0.98;return basePrice * discountFactor;}
接下来我开始替换临时变量,每次一个。首先我把赋值(basePrice)动作的右侧表达式提炼出来:
double getPrice() {// 将变量右边的表达式提取到新函数中final int basePrice = basePrice();final double discountFactor;if (basePrice > 1000) discountFactor = 0.95;else discountFactor = 0.98;return basePrice * discountFactor;}// 创建新函数private int basePrice() {return _quantity * _itemPrice;}
编译并测试,如果没有问题就开始使用Replace Temp with Query。
首先把临时变量basePrice的第一个引用点替换掉:
double getPrice() {final int basePrice = basePrice();final double discountFactor;// 替换掉basePrice变量第一个引用点,替换为新的函数if (basePrice() > 1000) discountFactor = 0.95;else discountFactor = 0.98;return basePrice * discountFactor;}
编译,测试。然后替换下一个引用点,直到所有的引用点都替换掉。
然后把basePrice临时变量的声明式一并摘除
double getPrice() {// 去掉了basePrice临时变量final double discountFactor;//临时变量替换为函数if (basePrice() > 1000) discountFactor = 0.95;else discountFactor = 0.98;//临时变量替换为函数return basePrice() * discountFactor;}
搞定basePrice之后,我再以类似办法提炼出一个discountFactor()
double getPrice() {final double discountFactor = discountFactor();return basePrice() * discountFactor;}//创建一个新函数private double discountFactor() {//复用了basePrice临时变量提炼的函数if (basePrice() > 1000) return 0.95;else return 0.98;}
你看,如果我没有把临时变量basePrice替换为一个查询式,将多么难以提炼discountFactor()
最终,getPrice()变成了这样
double getPrice() {return basePrice() * discountFactor();}