重构-改善既有代码的设计(一)

这篇文章是我对于《重构-改善既有代码的设计》一书的记录。

缘由

我们经常会遇到需要对之前的功能进行修改的局面,当我们重新阅读之前的代码的时候,可能会有这样的感受:“我当时到底是怎么想的啊,我根本看不懂了啊,要怎么加功能呢?写的和*一样”。如果你有这种想法的话,就说明你需要对之前的代码进行重构了。

概念

重构 是在不影响业务的外在表现的时候对代码进行修改和优化的行为。

重构应该是一种编码的思维方式,当你有空的时候就应该对之前的代码进行整理,因为你总会觉得之前的代码写的很烂的,就和你永远觉得兜里的钱很少一样。

方法

请不要把下面的方法当做唯一,因为这只是我脑袋还记得的东西:

  • 提炼函数
  • 移动函数
  • 数据封装

提炼函数

提炼函数 是一个非常常用的重构方式,当我们看到了一个代码行数很多的方法的时候就可以思考一样是不是可以对这个函数进行提炼了。 例如,我们有如下的一段代码:

void printOrder(double amount){
  printBanner();

  //print detail
  System.out.println("name:"+name);
  System.out.println("amount:"+amount);
}

对于这个方法我们可以对它进行提炼,有一个很好的入口就是,当我们看到了一段代码上面有一个注释的时候,我们就可以试着把这段代码单独作为一个方法提炼起来。重构之后就变成了了下面这样:

void printOrder(double amount){
  printBanner();
  printDetail(amount);
}

void printDetail(double amount){
  System.out.println("name:"+name);
  System.out.println("amount:"+amount);
}

提炼方法对于代码的理解是会有帮助的,通常我们阅读一个命名优美的方法名的时候就可以知道它的功能了,看详细的代码未必能够很快理解。

移动函数

如果一函数对于另外一个类的依赖大于本身的类,那么我们就可以尝试把这个方法转移到依赖的那个类了。 例如:

class Acount{
  ...
  long computeFee(){
    if(type == Premium){
      long result = 10;
      if(dayOverdrawn>7) result +=(dayOverdrawn -7)*0.85;
      return result;
    }else {
      return dayOverdrawn *1.75;
    }
  }

  long bankCharge(){
    long result = 4.5;
    if(dayOverdrawn >0) result +=computeFee();
    return result; 
  }
}

上面的方法对于type的依赖很高,对于不同的类型有不同的费用计算,这里我们可以把计算服务费的部分放入AccountType的类里面,如下:

class AccountType{
  long computeFee(int dayOverdrawn){
    if(type == Premium){
      long result = 10;
      if(dayOverdrawn>7) result +=(dayOverdrawn -7)*0.85;
      return result;
    }else {
      return dayOverdrawn *1.75;
    }
  }
}

然后在Account类里面替换一下引用就可以了:

class Acount{
  ...
  long bankCharge(){
    long result = 4.5;
    if(dayOverdrawn >0) result +=type.computeFee(dayOverdrawn);
    return result; 
  }
}

数据封装

如果我们有一个列表项,但是必须要和其他的数据结合起来才有意义,那么我们可以使用数据封装的方式,使用对象替换数据值。
例如,我们有一个订单的类,里面有购买者的基本信息(这只是一个小例子):

class Order{
  String orderId;
  String customName;
  String customPhone;
  public String getCustomName(){
    return customName;
  }

  public String getCustomPhone(){
    return customPhone;
  }
}

对于上面的订单类,我们可以把购买者单独作为一个类存在:

class Custom{
  String customName;
  String customPhone;
  public String getCustomName(){
    return customName;
  }

  public String getCustomPhone(){
    return customPhone;
  }
}

然后在Order类里面使用Custom来替换之前的购买者信息。 未完待续…

Search by:GoogleBingBaidu