提出问题

项目中的函数如何重构???

解决问题

以下是来自《重构》这本书个人的一些总结,加上自己写的一些小例子,例子有点扯,只是倡导快乐学习而已,希望大家能够喜欢:

Introduce Explaining Variable(引入解释性变量)

你有一个复杂的表达式,将该表达式的结果放进一个临时变量,以此变量名称来解释表达式用途。

事实上该方法和Extract Method处理方式相反,作者个人喜欢用Extract Method,我的观点和作者一样的。

例一:

  1. public String testLove(){
  2. if((flowerNum * day > 999) && (callMinute * day) >999 && (sayLoveNum * day) >999){
  3. return "真爱";
  4. }else{
  5. return "Get out";
  6. }
  7. }

Introduce Explaining Variable重构:

  1. public String testLove(){
  2. int totalFlowerNum = flowerNum * day;
  3. int totalCallMinuteNum = callMinute * day;
  4. int totalSayLoveNum = sayLoveNum * day;
  5. if((totalFlowerNum> 999) && totalCallMinuteNum>999 && totalSayLoveNum >999){
  6. return "真爱";
  7. }else{
  8. //有人和我说“滚”,太粗俗,我就用英文吧!
  9. return "Get out";
  10. }
  11. }

Extract Method重构(作者推荐):萝卜蔬菜,个人所爱吧!

  1. public String testLove(){
  2. if((getTotalFlowerNum()> 999) && getTotalCallMinuteNum()>999 && getTotalSayLoveNum() >999){
  3. return "真爱";
  4. }else{
  5. return "Get out";
  6. }
  7. }
  8. public int getTotalFlowerNum(){
  9. return flowerNum * day;
  10. }
  11. public int getTotalCallMinuteNum(){
  12. return callMinute * day;
  13. }
  14. public int getTotalSayLoveNum(){
  15. return sayLoveNum * day;
  16. }

Split Temporary Variable(分解临时变量)

你的程序有某个临时变量被赋值超过一次,它既不是循环变量,也不被用于收集计算结果。针对每次赋值,创造一个独立,对应的临时变量。

临时变量应该只被赋值一次。如果它被赋值超过一次,就意味它们在函数中承担了一个以上的责任。如果临时变量承担多个责任,它就应该被替换为多个临时变量。

可以将新的临时变量声明为final来确认是否被赋值多次。

Remove Assignments to Parameters(移除对参数赋值)

代码对一个参数进行赋值。以一个临时变量取代该参数的位置

例二:

  1. int testLove(int flowerNum,int callMinuteNum){
  2. if(flowerNum >50) flowerNum -=2;
  3. return flowerNum;
  4. }

重构后:

  1. int testLove(int flowerNum,int callMinuteNum){
  2. int result = flowerNum;
  3. if(result >50) result -=2;
  4. return result;
  5. }

再次重构:可以为参数加上关键词final,从而强制它遵守“不对参数赋值”这一惯例

  1. int testLove(final int flowerNum,final int callMinuteNum){
  2. int result = flowerNum;
  3. if(result >50) result -=2;
  4. return result;
  5. }

但是final对于提高短函数的清晰度,并无太大帮助。通常会在较长的函数中使用它,让它帮助我检查参数是否被做了修改。

Replace Method with Method Object(以函数对象取代函数)

你有一个大型函数,其中对局部变量的使用使你无法采用Extract Method。将这个函数放进一个单独对象中,如此一来局部变量就成了对象内的字段。然后你可以在同一个对象中将这个大型函数分解为多个小型函数。

例三:假如下面是一个很长很长的函数,我们使用重构方法

  1. public String test(){
  2. int sendDay = 1000;//坚持送了几天
  3. int flowerNum = 9;//花朵数量
  4. int engagementDay = 100000;//约会天数
  5. int callMinuteTimes = 10000;
  6. if(engagementDay > 100000){
  7. return engagementDay + "--" + "可以结婚了,姑娘!!";
  8. }else if(callMinuteTimes > 10000){
  9. return callMinuteTimes + "--" + "可以考虑了,姑娘!!";
  10. }else if(sendDay * flowerNum >999999){
  11. return sendDay * flowerNum + "--" + "这是一个好小伙!!!";
  12. }else{
  13. return "待定";
  14. }
  15. }

重构:

  1. package com.evada.de;
  2. /**
  3. * Created by Ay on 2016/8/27.
  4. */
  5. public class LoveTest {
  6. //源对象引用,重构过程中可能需要调用源对象的方法
  7. private AyTest ayTest;
  8. private int sendDay;
  9. private int flowerNum = 0;
  10. private int engagementDay = 0;
  11. private int callMinuteTimes = 0;
  12. public LoveTest() {}
  13. //构造方法,全部定义为final,避免被修改
  14. public LoveTest(final AyTest ayTest,final int sendDay,final int flowerNum ,
  15. final int engagementDay,final int callMinuteTimes){
  16. this.ayTest = ayTest;
  17. this.sendDay = sendDay;
  18. this.flowerNum = flowerNum;
  19. this.engagementDay = engagementDay;
  20. this.callMinuteTimes = callMinuteTimes;
  21. }
  22. //从源对象copy过来,进行修改即可
  23. public String testLove(){
  24. if(engagementDay > 100000){
  25. return engagementDay + "--" + "可以结婚了,姑娘!!";
  26. }else if(callMinuteTimes > 10000){
  27. return callMinuteTimes + "--" + "可以考虑了,姑娘!!";
  28. }else if(sendDay * flowerNum >999999){
  29. return sendDay * flowerNum + "--" + "这是一个好小伙!!!";
  30. }else{
  31. return "待定";
  32. }
  33. }
  34. }

通过上面的修改,我们就可以利用之前学过的方法,对testLove这个方法进行更多重构。