重构:改善既有代码设计——第八章笔记

8.1搬移函数

动机:根本目的是为了更好的模块化,直接原因是:如果一个函数频繁引用其他上下文,可能说明这个函数跟另一个上下文的关系更加紧密,此时,让这个函数与那些更亲密的元素相会,也许可以取得更好的封装效果。

在类之间搬移函数

class Acount{
  double getBankCharge(){
    double result = 4.5;
    if(this.daysOverdraw > 0) result += getOverdraftCharge();
    return result;
  }
  double getOverdraftCharge(){
    if(this.type.getIsPremium()){
      double baseCharge = 10;
      if(this.daysOverdraw <= 7)
        return baseCharge;
      return baseCharge + (this.daysOverdraw - 7)*0.85;
    } else {
      return this.daysOverdrawn * 1.75;
    }
  }
}
//可以看到,OverdraftCharge透支金额折扣计算与账户的类型this.type有关,所以可以考虑移动到type类型中
//而daysOverdrawn与具体的账户有关,所以不能移动都type类型,需要通过参数传递
class AcountType{
  Boolean isPremium;
  double getOverdraftCharge(double daysOverdrawn){
    if(this.getIsPremium()){
      double baseCharge = 10;
      if(daysOverdraw <= 7)
        return baseCharge;
      return baseCharge + (daysOverdraw - 7)*0.85;
    } else {
      return daysOverdrawn * 1.75;
    }
  }
}
class Acount{
    double getOverdraftCharge(){
      return this.type.getOverdraftCharge(this.daysOverdraw);
      //也可以直接内联到getBankCharge函数中
    }
}
8.2搬移字段

动机:良好的数据结构是一个健壮程序的根基,但很难一开始便能设计好的数据结构。

发现:

  • 传入一个参数时,总是需要传入另一个记录的某条字段
  • 总是一同出现,一同作为函数传递的数据——和数据泥团有什么区别?
  • 修改一条记录时,总是需要改动另一条记录
  • 更新一个字段,总是要再多个结构中同时修改
class Customer{
  String name;
  double disCountRate;
  CustomerContract contract = new CustomerContract(new Today());
  //使用到discount的函数
  double usedDisCount(){
    return this.disCountRate = this.disCountRate + 0.3;
  }
}
class CustomerContract{
  private Day day;
  public CustomerContract(Day day){
    this.day = day;
  }
}
//希望把顾客中的discountRate移动到合同中
class Cutomer(){
  double getDisCount(){
    return this.contract.getDisCountRate();
  }
  void setDisCount(double discount){
    this.contract.setDisCountRate(discount);
  }
    //使用到discount的函数
  double usedDisCount(){
    return getDisCount() + 0.3;
  }
}
class CutomerContract(){
  double disCountRate();
}
8.3搬移语句到函数

动机:消除重复代码

8.4搬移语句到调用者

动机:程序的抽象能力来自函数,而抽象边界并非总是很好平衡,随着系统的演进,边界可能已经偏移:曾经视为一个整体的行为,可能已经分化出多个不同的关注点,以往多个地方共用的行为,现在可能需要在某些调用点表现出不同的行为。

步骤:先提炼函数,再在调用点进行内联

8.5 以函数调用取代内联代码

动机:可以将相关行为打包,通过良好的函数命名提升代码的表达能力。

8.6移动语句

动机:让存在关联的代码一起出现,可以使代码更容易理解。

8.7拆分循环

动机:经常有身兼多职的循环,若在一次循环中做了多件事情,意味着需要同时理解多件事情,而拆分循环可以让你一次只理解一件事情。此外,拆分循环后还可以提炼函数,将每一个循环提炼到有单独意义的函数。

People[] peoples = getAllPeoples();
for(People people : peoples){
  if(paople.age < youngest)
    youngest = people.age;
  totalSalary+=people.salary;
}
//重构后
double getYoungest(){
  ...
  for(People people : peoples){
  	if(paople.age < youngest)
    	youngest = people.age;
	}
  return youngest;
}
double getTotalSalary(){  
  for(People people : peoples){
    totalSalary+=people.salary;
  }
  return totalSalary;
}
8.8以管道取代循环

动机:增强代码可读性

java中的stream

8.9移除死代码

动机:消除无用代码带来是思维负担

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值