重构之临时变量(Replace Temp with Query)
当你的程序以一个临时变量保存某一表达式的运算结果
将这个表达式提炼到一个独立函数中,将这个临时变量的所有[被引用点]替换为[对新函数的调用],新函数可被其他函数使用
- double basePrice=_quantity * _itemPrice;
- if(basePrice>1000){
- return basePrice * 0.95;
- else
- return basePrice * 0.38;
- }
- ......
提炼后:
- if (basePrice()>1000){
return basePrice() * 0.95 - else
- return basePrice() * 0.38
- }
- ......
- double basePrice(){
- return _quantity * _itemPrice;
}
动机:
临时变量的问题在于:它们是暂时的,而且只能在所属函数内使用,由于临时变量只有在所属内才可见,所以它们会驱使你写出更长的函数,因为只有这样你才能访问到想要访问的临时变量,如果把临时变量替换为一个查询式(query method),那么同一个CLASS中的所有函数都将获得这份信息。这将带给你极大帮助,使你能够为这个CLASS编写更清晰的代码。
这个重构手法较为直率的情况就是:临时变量只被赋值一次,或者赋值给临时变量的表达式不受其他条件影响,其他情况比较情况棘手,但也有可能发生,你可能需要先运用Split Temporary Variable 或Separate Query from Modifier 使情况变得简单一些。如果你想替换的临时变量是用来收集结果的(例如循环中的累加值),你就需要将某些程序的逻辑(例如循环)拷贝到查询式(query method)去。
作法:
- 找出只被赋值一次的临时变量
- 将临时变量声明为 final
- 编译(这可确保临时变量的确只被赋值一次)
- 将对该临时变量赋值之语句的等号右侧部分提炼到一个独立函数中。详细步骤:首先将函数声明为private,之后你可能会发现有更多CLASS需要使用它,彼时你可轻易放松对它的保护。确保提炼出来的函数无任何连带影响,就对它进行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;
- }
我希望将这个两个变量都替换掉,当然,每次一个。
尽管这里的代码十分清楚,我还是先把临时变量声明为final,检查它们是否的确只被赋值一次:
- double getPrice()
- {
- final int basePrice = _quantity * _itemPrice;
- final double discountFactor;
- if(basePrice>1000)
- discountFactor=0.95;
- else
- discountFactory=0.98;
- return basePrice * discountFactor;
- }
这么一来,如果有任何问题,编译器就会警告我,之所以先做这件事,因为如果临时变量不只被赋值一次,不该进行这项重构了,接下来我开始替换临时变量了,每次一个,首先我把赋值动作的右侧表达式提炼出来。
- 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;
- }
再把临时变量的引用点替换掉:
- double getPrice()
- {
- final int basePrice = basePrice();
- final double discountFactor;
- if ( basePrice()>1000 )
- discountFactor = 0.95;
- else
- discountFactor = 0.98;
- return basePrice() * discountFactor;
- }
下一步:
- double getPrice()
- {
- final double discountFactor;
- if ( basePrice()>1000 )
- discountFactor = 0.95;
- else
- discountFactor = 0.98;
- return basePrice() * discountFactor;
- }
下一步(仔细观察代码)
- double getPrice()
- {
- return basePrice() * discountFactor();
- }
- private double discountFactor()
- {
- if ( basePrice()>1000 )
- return 0.95;
- else
- return 0.98;
- }
- private int basePrice()
- {
- return _quantity * _itemPrice;
- }
是多么简单啊(代码有错请指点)
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 4260 次
- 性别:

- 来自: 北京

- 详细资料
搜索本博客
我的相册
共 6 张
最近加入圈子
最新评论
-
glassfish服务器推送技术
很好,我们公司也在考虑换glassfish,就是为了推..
-- by sway -
glassfish服务器推送技术
我想问你com.sun.enterprise.web.connector.gri ...
-- by TITLE02 -
好不容易打个电话
汗。。。。
-- by javaoldboy -
请教:spring+hbernate sea ...
直接按照hibernate annottion文档标识UUID生存即可,不需要改 ...
-- by liuzongan -
请教:spring+hbernate sea ...
麻烦能具体说一下解决过程吗?还有,如果使用UUID生成主键应该怎样标识主键的生成 ...
-- by roy042






评论排行榜