代码的味道--烟熏鲱鱼1

2016-07-25  本文已影响34人  whyreal

烟熏鲱鱼(臭臭)

指那些已经被添加了太多属性或者方法的,难以维护的的函数或类。通常这种情况不是突然出现的,而是随着代码进化而不断积累,特别是在没有人专门维护代码的时候。

超长的方法

原文链接

特征和症状

一个方法中包含了太多行代码。在一个方法中如果代码超过10行,那就应该考虑拆分。一个方法中的代码越多,你越难看清楚这个方法到底干了什么。

原因

就像加州旅馆,代码被不断的加入到一个方法中但是却从来不删除代码。因为写代码要比读代码容易的多,这种气味通常不易察觉,直到有一天你的代码变成怪异的,超重的怪兽。

人们往往不愿意创建新的方法,而更愿意将代码塞在已有的方法里:“就两行代码,没必要写个新函数”,于是不断就“两行代码“加入进来。正这是这种想法导致方法面变得越来越长,最后变成一团乱麻。

解决办法

只有一条规则:如果你觉得需要为方法里的代码写注释,那么你就应该为那些代码新建一个方法。即使需要被注释的的代码只有一行也应该这么做。如果代码有了一个可以描述的名字(方法名),其他人就可以安心的跳过这部分代码,去看他们想看的部分。

你有一些可以被分组的代码

void printOwing() {
  printBanner();

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

将这些代码拆分到新的方法中

void printOwing() {
  printBanner();
  printDetails(getOutstanding());
}

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

你会将一个表达式的结果赋值给本地变量,以便稍后使用

double calculateTotal() {
  double basePrice = quantity * itemPrice;
  if (basePrice > 1000) {
    return basePrice * 0.95;
  }
  else {
    return basePrice * 0.98;
  }
}

你可以将整个表达式拆分到新的方法中,然后以函数执行代理本地变量

double calculateTotal() {
  if (basePrice() > 1000) {
    return basePrice() * 0.95;
  }
  else {
    return basePrice() * 0.98;
  }
}
double basePrice() {
  return quantity * itemPrice;
}

如果你有一组接受相同参数的方法,那么你应该讲这些参数封装在一个新的对象里。

如果你从一个对象中获得多个值,然后将这些值传递给一个方法

int low = daysTempRange().getLow();
int high = daysTempRange().getHigh();
boolean withinPlan = plan.withinRange(low, high);

可以将整个对象当做参数传递

boolean withinPlan = plan.withinRange(daysTempRange());

使用了太多的局部变量导致没办法进行方法拆分

class Order {
  //...
  public double price() {
    double primaryBasePrice;
    double secondaryBasePrice;
    double tertiaryBasePrice;
    // long computation.
    //...
  }
}

可以将这个方法改写成类,这样,局部变量就编程了函数的属性,然后就可以对之前的方法进行拆分了。

class Order {
  //...
  public double price() {
    return new PriceCalculator(this).compute();
  }
}

class PriceCalculator {
  private double primaryBasePrice;
  private double secondaryBasePrice;
  private double tertiaryBasePrice;
  
  public PriceCalculator(Order order) {
    // copy relevant information from order object.
    //...
  }
  
  public double compute() {
    // long computation.
    //...
  }
}

你有一系列复杂的条件判断(if-then / else or switch)

if (date.before(SUMMER_START) || date.after(SUMMER_END)) {
  charge = quantity * winterRate + winterServiceCharge;
}
else {
  charge = quantity * summerRate;
}

将条件判断中复杂的部分拆分到单独的方法中

if (notSummer(date)) {
  charge = winterCharge(quantity);
}
else {
  charge = summerCharge(quantity);
}

负债

性能

有人会担心方法数量的增加会导致程序性能的下降,的确是这样。但是大部分情况下这种影响可以忽略不计。但好的方面是:如果你把代码弄得简单明了,那么必要的时候你很容易对代码进行优化。

上一篇 下一篇

猜你喜欢

热点阅读