java 代码细节(Replace Temp with Query)
来源:互联网 发布:超人 知乎 编辑:程序博客网 时间:2024/04/19 10:56
这个观点来自《重构-----改善既有代码的设计》
You are using a temporary variable to hold the result of an expression.
02Extract the expression into a method. Replace all references to the temp with the expression. The new method can then be used in other methods.
03double basePrice = _quantity * _itemPrice;if (basePrice > 1000) return basePrice * 0.95;else return basePrice * 0.98;
04if (basePrice() > 1000) return basePrice() * 0.95;else return basePrice() * 0.98;...double basePrice() { return _quantity * _itemPrice;}
Motivation
05The problem with temps is that they are temporary and local. Because they can be seen only in the context of the method in which they are used, temps tend to encourage longer methods, because that’s the only way you can reach the temp. By replacing the temp with a query method, any method in the class can get at the information. That helps a lot in coming up with cleaner code for the class.
06Replace Temp with Query often is a vital step before Extract Method. Local variables make it difficult to extract, so replace as many variables as you can with queries.
07The straightforward cases of this refactoring are those in which temps are assigned only to once and those in which the expression that generates the assignment is free of side effects. Other cases are trickier but possible. You may need to use Split Temporary Variable or Separate Query from Modifier first to make things easier. If the temp is used to collect a result (such as summing over a loop), you need to copy some logic into the query method.
Mechanics
08Here is the simple case:
09- Look for a temporary variable that is assigned to once.If a temp is set more than once consider Split Temporary Variable.
- Declare the temp as final.
- Compile.This will ensure that the temp is only assigned to once.
- Extract the right-hand side of the assignment into a method.Initially mark the method as private. You may find more use for it later, but you can easily relax the protection later.
Ensure the extracted method is free of side effects, that is, it does not modify any object. If it is not free of side effects, use Separate Query from Modifier. - Compile and test.
- Use Replace Temp with Query on the temp.
Temps often are used to store summary information in loops. The entire loop can be extracted into a method; this removes several lines of noisy code. Sometimes a loop may be used to sum up multiple values, as in the example on page 26. In this case, duplicate the loop for each temp so that you can replace each temp with a query. The loop should be very simple, so there is little danger in duplicating the code.
11You may be concerned about performance in this case. As with other performance issues, let it slide for the moment. Nine times out of ten, it won’t matter. When it does matter, you will fix the problem during optimization. With your code better factored, you will often find more powerful optimizations, which you would have missed without refactoring. If worse comes to worse, it’s very easy to put the temp back.
Example
12I start with a simple method:
13double getPrice() { int basePrice = _quantity * _itemPrice; double discountFactor; if (basePrice > 1000) discountFactor = 0.95; else discountFactor = 0.98; return basePrice * discountFactor;}
14I’m inclined to replace both temps, one at a time.
15Although it’s pretty clear in this case, I can test that they are assigned only to once by declaring them as final:
16double getPrice() { final int basePrice = _quantity * _itemPrice; final double discountFactor; if (basePrice > 1000) discountFactor = 0.95; else discountFactor = 0.98; return basePrice * discountFactor;}
17Compiling will then alert me to any problems. I do this first, because if there is a problem, I shouldn’t be doing this refactoring. I replace the temps one at a time. First I extract the right-hand side of the assignment:
18double 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;}
19I compile and test, then I begin with Replace Temp with Query. First I replace the first reference to the temp:
20double getPrice() { final int basePrice = basePrice(); final double discountFactor; if (basePrice() > 1000) discountFactor = 0.95; else discountFactor = 0.98; return basePrice * discountFactor;}
21Compile and test and do the next (sounds like a caller at a line dance). Because it’s the last, I also remove the temp declaration:
22double getPrice() { final double discountFactor; if (basePrice() > 1000) discountFactor = 0.95; else discountFactor = 0.98; return basePrice() * discountFactor;}
23With that gone I can extract discountFactor in a similar way:
24double getPrice() { final double discountFactor = discountFactor(); return basePrice() * discountFactor;} private double discountFactor() { if (basePrice() > 1000) return 0.95; else return 0.98;}
25See how it would have been difficult to extract discountFactor
if I had not replaced basePrice
with a query.
The getPrice
method ends up as follows:
double getPrice() { return basePrice() * discountFactor();}
- java 代码细节(Replace Temp with Query)
- Replace Temp with Query
- 6.4replace temp with query
- Inline Temp & Replace Temp with Query
- 重构:Replace Temp with Query
- 读书笔记-重构-Replace Temp with Query
- 重构:Replace Temp with Query
- 《重构》读书笔记 --Replace Temp with Query
- refactoring笔记——代码重构的方法:Replace Temp with Query
- 使用Eclipse重构代码——Replace Temp with Query
- java重构学习3:以查询代替临时变量(Replace Temp with Query)
- Replace Temp With Query(以查询取代临时变量)
- 6.4 Replace Temp with Query(以查询取代临时变量)
- Replace Temp with Query 以查询取代临时变量
- java 代码细节(inline temp)
- java 代码细节(Replace Method with Method Object)
- 重新组织函数--以查询取代临时变量(Replace Temp with Query)
- 重构---重构手法-----以查询取代临时变量(Replace Temp with Query)
- 线性标定校准的实现
- 建立数据元素值为字符型的顺序队列
- java 代码细节(inline temp)
- centos6.3如何安装中文输入法?
- 建立数据域值为字符型的链式队列
- java 代码细节(Replace Temp with Query)
- Spine的使用(With Cocos2d-x)
- Hibernate开发全面流程和开发配置
- centos 6.3下安装QQ2012
- Windows 8 乙肝自测隐私声明
- CentOS 6.2 下安装QQ2012完全可用
- boost使用简要指南
- 快速排序
- 关于java core的一些知识