重构方法及设计思路
- 格式:docx
- 大小:113.68 KB
- 文档页数:42
重构方法(1) -
提取方法
描述:
当你的代码中有一些片段在逻辑上能够归为一组,那么通常可以将这一组代码提取出来形成一个方法,并用方法名来解释方法的目的。
动机:
1. 提高了其他方法重用这段代码的可能性。
2. 使得‘高层’的方法可读性更好。
3. 当有需要的时候,重载更加方便。
步骤:
1. 创建一个新方法,以方法的目的为该方法命名(而不是以方法的具体行为为该方法命名)。
2. 把要提取的方法从原来的方法中拷贝到新方法中。
3. 检查提取的代码,看看其中是否有对原来方法中的局部变量的引用(通常IDE会帮我们做,会用编译错误来提示找不到变量)。如果有,将该变量作为方法的参数。
4. 检查在原方法中是否有只在提取的代码中使用的临时变量,如果有,将该变量移入提取的方法中。
5. 看看在第三步中的局部变量在方法中是否被改变了。如果只有一个局部变量被改变,那么我们可以将该变量作为方法的返回值返回。如果有多于一个的变量被改变,那么我们可能需要先进行'分离临时变量'(另外一种重构方法,以后介绍)重构,再进行提取方法的重构。我们以可以使用'使用查询方法代替临时变量'(另外一种重构方法,以后介绍)来减少临时变量的个数。
6. 编译代码,看看是否有错误。
7. 用提取的方法替换原来方法中被提取的代码。注意在原方法中删除第四步中我们移入的临时变量。
8. 编译,运行单元测试。
例子:
1. 没有局部变量的情况
1. void printOwing(){
2. Enumeration e = _orders.elements();
3. double outstanding = 0.0;
4.
5.
6.
7. //打印提示信息
8. System.out.println(“************************”); 9. System.out.println(“***** Customer
10. Owes *****”);
11. System.out.println(“************************”);
12.
13.
14.
15. //计算应付金额
16. while (e.hasMoreElements()) {
17.
Order each = (Order) e.nextElement();
18. outstanding += each.getAmount();
19. }
20.
21.
22.
23. //打印详细信息
24. System.out.println(“name:” +
25. _name);
26. System.out.println(“amount:” +
27. outstanding);
28. }
复制代码
在这里,我们可以很容易的将打印提示信息的部分代码提取成单独的方法。
1. void printOwing(){
2. Enumeration e = _orders.elements();
3. double outstanding = 0.0;
4.
5.
6.
7. printBanner();
8.
9.
10. 11. //计算应付金额
12. while (e.hasMoreElements()) {
13. Order each = (Order) e.nextElement();
14. outstanding += each.getAmount();
15. }
16.
17.
18.
19. //打印详细信息
20. System.out.println(“name:” +
21. _name);
22. System.out.println(“amount:” +
23. outstanding);
24. }
25.
26.
27.
28. void printBanner(){
29. System.out.println(“************************”);
30. System.out.println(“*****
31. Customer Owes *****”);
32. System.out.println(“************************”);
33. }
复制代码
2. 提取代码中读取局部变量的情况
还是使用上面的代码,我们来提取打印详细信息的方法。
1. void printOwing(){
2. Enumeration e = _orders.elements();
3. double outstanding = 0.0;
4.
5.
6.
7. printBanner(); 8.
9.
10.
11. //计算应付金额
12. while (e.hasMoreElements()) {
13. Order each = (Order) e.nextElement();
14. outstanding += each.getAmount();
15. }
16.
17.
18.
19. printDetail(outstanding);
20. }
21.
22.
23.
24. void
25. printBanner(){
26. System.out.println(“************************”);
27. System.out.println(“*****
28. Customer Owes *****”);
29. System.out.println(“************************”);
30. }
31.
32.
33.
34. void
35. printDetail(double outstanding){
36. System.out.println(“name:” +
37. _name);
38. System.out.println(“amount:”
39. + outstanding); 40. }
复制代码
可以看到,我们将在提取的代码中要读取的局部变量作为方法的参数传入。
3. 局部变量重新赋值的情况
下面我们来看看提取计算应付金额的方法。由于这段代码中对局部变量outstanding进行了重新赋值,因此提取后的结果如下:
1. void printOwing(){
2. printBanner();
3. double outstanding = getOutstanding();
4. printDetail(outstanding);
5. }
6.
7. void printBanner(){
8. System.out.println(“************************”);
9. System.out.println(“***** Customer Owes *****”);
10. System.out.println(“************************”);
11. }
12.
13. void printDetail(double outstanding){
14. System.out.println(“name:” + _name);
15. System.out.println(“amount:” + outstanding);
16. }
17.
18. double getOutstanding(){
19. Enumeration e = _orders.elements();
20. double result = 0.0;
21.
22. while (e.hasMoreElements()) {
23. Order each = (Order) e.nextElement();
24. result += each.getAmount();
25. }
26. 27. return result;
28. }
复制代码
可以看到,被重新赋值的局部变量作为返回值返回了
[软件改进] 重构方法(2) - 内联方法
描述:
如果方法的内容很简短并且非常容易理解,我们可以在调用该方法的语句中直接使用方法体的内容,这样可以移除这个方法。
动机:
重构的一个主题就是使用方法名来表明方法的功能,这样可以带来更加清晰易读的代码。但是如果方法体和方法名一样清晰易懂,这个时候使用方法就不必要了。
另外一个使用内联方法重构的时机是当我们有一组构建的很差的方法需要进行重构,我们可以将所有的方法体都放到原来的大的方法中,然后在使用提取方法来重构代码。