提出问题

项目开发中函数如何重构???

解决问题

以下是<重构>这本书的几点总结,方法重构在项目中是最经常使用到的.

Extract Method(提炼函数)

当我看见一个过长的函数,或者一段需要注释,才能让人理解用途的代码,我就会将这段代码放进一个独立函数中。

例一:这是最简单的重构

  1. /**
  2. * Created by Ay on 2016/8/24.
  3. */
  4. public class AyTest {
  5. public static void test() {
  6. printBanner();
  7. //print detail
  8. System.out.println("print:1");
  9. System.out.println("print:2");
  10. }
  11. public static void printBanner(){
  12. System.out.println("printBanner");
  13. }
  14. }

重构后如下:每个函数的粒度越小,被重用的机会就越大,函数的名字一定要取好,这点很重要的,名字取到你不需要添加任何注释既可以满意了

/**
* Created by Ay on 2016/8/24.
*/
public class AyTest {
   //这是重构的方法,个人习惯把它放到上面,与调用函数靠近,方便阅读
   public static void printDetail(){
       //print detail
       System.out.println("print:1");
       System.out.println("print:2");
   }
   public static void test() {
       printBanner();
       printDetail();  
   }
   public static void printBanner(){
       System.out.println("printBanner");
   }
}

无局部变量与有局部变量

上面例一的printDetail()就是无局部变量的重构

例二:

/**
* Created by Ay on 2016/8/24.
*/
public class AyTest {
   public List<String> initData(){
       List<String> list = new ArrayList<>();
       list.add("吃饭");
       list.add("睡觉");
       list.add("打豆豆");
       return list;
   }
   public void test() {
       List<String> list = initData();
       //局部变量,可以消除掉,具体看下面重构方法
       double totalStrLength = 0;
       printBanner();
       Iterator iterator = list.iterator();
       while (iterator.hasNext()){
           String str = (String)iterator.next();
           totalStrLength = totalStrLength + str.length();
       }
       //print detail
       System.out.println("print:1");
       System.out.println("print:2");
   }
   public void printBanner(){
       System.out.println("printBanner");
   }
}

重构后:

/**
* Created by Ay on 2016/8/24.
*/
public class AyTest {
   public List<String> initData(){
       List<String> list = new ArrayList<>();
       list.add("吃饭");
       list.add("睡觉");
       list.add("打豆豆");
       return list;
   }
   public double getTotalStrLength(List<String> list){
       double totalStrLength = 0.0;
       Iterator iterator =  list.iterator();
       while (iterator.hasNext()){
           String str = (String)iterator.next();
           totalStrLength = totalStrLength + str.length();
       }
       return totalStrLength;
   }
   public void test() {
       List<String> list = initData();
       printBanner();
       //重构后的代码,我放在上面
       double totalStrLength = getTotalStrLength(list);
       //重构后代码,我放在下面,这样一目了然
       printDetail();
   }
   //这是重构的方法,个人习惯把它放到上面,与调用函数靠近,方便阅读
   public static void printDetail(){
       //print detail
       System.out.println("print:1");
       System.out.println("print:2");
   }
   public void printBanner(){
       System.out.println("printBanner");
   }
}

Inline Method(内联函数)

在函数调用点插入函数主体,然后移除该函数

例三:

public String getLoveInfo(){
   //鲜花数量
   int flowerNum = 999;
   return isLoveMe(flowerNum)?"爱你":"滚";
}
public boolean isLoveMe(int num){
   return num>999?true:false;
}

重构

public String getLoveInfo(){
   //鲜花数量
   int flowerNum = 999;
   return (flowerNum>999)?"爱你":"滚";
}

Inline Temp(内联临时变量)

例四:

/**
* Created by Ay on 2016/8/24.
*/
public class AyTest {
   public String testLove(){
       double flowerNum = bugFlower();
       return flowerNum >999?"真爱":"待定";
   }
   public int bugFlower(){
       return 999;
   }
}

重构:

/**
* Created by Ay on 2016/8/24.
*/
public class AyTest {
   public String testLove(){
       return buyFlower()>999?"真爱":"待定";
   }
   public int buyFlower(){
       return 999;
   }

Replace Temp Whit Query(以查询取代临时变量)

例五

public String test(){
   int sendDay = 10;//坚持送了几天
   int flowerNum = 9;//花朵数量
   int engagementDay = sendDay * flowerNum;//约会天数
   if(engagementDay > 100){
       return engagementDay + "--" + "可以结婚";
   }else{
       return engagementDay + "--" + "发放好人卡";
    }
}

重构:将一个表达式提炼到一个独立函数中,将这个临时变量的所有引用点替换为对新函数的调用,此后词函数就可以被其他函数使用

public String test(){
   int sendDay = 10;//坚持送了几天
   int flowerNum = 9;//花朵数量
   if(getEngagementDay(sendDay,flowerNum) > 100){
       return getEngagementDay(sendDay,flowerNum) + "--" + "可以结婚";
   }else{
       return getEngagementDay(sendDay,flowerNum) + "--" + "发放好人卡";
   }
}
public int getEngagementDay(int sendDay,int flowerNum){
   return sendDay * flowerNum;
}