代码重构

试想场景:

我们要写一个逻辑比较复杂的函数,

发现根之前一个函数很类似。

怎么办,

重新写?

or

coppy ——update——done

坏处?

重构?

一 以多态取代条件表达式 

为什么少用switch语句?

class Employee { 
    @Autowired
    private EmployeeType _type; 
    int getType() { 
     return _type.getTypeCode(); 
   }
    int payAmount(Employee emp){ 
      switch(getType()) {
      case EmployeeType.ENGINEER:  
           return emp.getMonthlySalary();
      case EmployeeType.SALESMAN: 
           return emp.getMonthlySalary() + emp.getCommission();
      case EmployeeType.MANAGER: 
           return emp.getMonthlySalary() + emp.getBonus(); 
      ... 
     default: throw new RuntimeException("Incorrect Employee"); 
     }
  }
}
 
abstract class EmployeeType { 
      abstract int getTypeCode(); 
   }

class Engineer extends EmployeeType {
    @Override
    int getTypeCode() {
    return Employee.ENGINEER; 
    } 
}

重构后

class Employee { 
    public Employee(EmployeeType type) {
      this._type = type
    } 
    int payAmount(Employee emp) { 
      return _type.payAmount(emp); 
    } 
  }

class EmployeeType { 
    abstract int payAmount(Employee emp); 
}

class Engine extends EmployeeType { 
    @Override
    int payAmount(Employee emp) { 
     return emp.getMonthlySalary(); 
    } 
} 
 
class Salesman extents EmployeeType { 
     @Override
     int payAmount(Employee emp) { 
        return emp.getMonthlySalary() + emp.getCommission(); 
     } 
}

class Manager extents EmployeeType { 
    @Override
    int payAmount(Employee emp) { 
         return emp.getMonthlySalary() + emp.getBonus(); 
    } 
}

二 过长参数列 

1.以函数取代参数 

重构前

public double getPrice() { 
     int basePrice = _quantity * _itemPrice; 
     int discountLevel;
     if(_quantity > 100){ 
         discountLevel = 2; 
     }else{ 
        discountLevel = 1; 
     } 
     double finalPrice = discountedPrice(basePrice, discountLevel); 
  return finalPrice; 
} 

private double discountedPrice(int basePrice, int discountLevel) { 
     if(discountLevel == 2) { 
         return basePrice * 0.1; 
     }else { 
         return basePrice * 0.05; 
     } 
}

重构后

public double getPrice() {
     return discountedPrice(); 
}

private doulbe discountedPrice() {
     if(getDiscountLevle() == 2){ 
         return getBasePrice() * 0.1; 
    } else{ 
         return getBasePrice() * 0.05; 
    } 
 }
private int getDiscountLevle() { 
     if(_quantity > 100){
         return 2; 
     } else{
         return 1; 
     } 
 }

 private double getBasePrice() { 
      return _quantity * _itemPrice; 
 }

对调用discountedPrice方法处使用内联函数,进一步重构

public double getPrice() {
     return discountedPrice(); 
}
继续,内联函数变成
public double getPrice() {
     if(getDiscountLevle() == 2) { 
         return getBasePrice() * 0.1; 
     } else{ 
         return getBasePrice() * 0.05; 
     } 
}

2.保持完整对象 

重构前

int low = daysRange.getLow(); 
int high = daysRange.getHigh(); 
withplan = plan.range(low, high); 

重构后

withplan = plan.range(daysRange); 

3引入参数对象.

重构前 

int low = daysRange.getLow(); 
int high = daysRange.getHigh(); 
int start = getStart(); 
int end = getEnd(); 

class Plan() {
     withplan = plan.range(low, high, start,end); 
}

重构后

int low = daysRange.getLow(); 
int high = daysRange.getHigh(); 
int start = getStart(); 
int end = getEnd(); 

class DaysCon() { 
   int low; 
   int high;
   int start;
   int end; 
}


class WithPlan() { 
   withplan = plan.range(daysCon); 
}

三 过长函数 

1.提炼函数(主要手段)

重构前 

public void PrintOwing(double amount) {
   PrintBanner(); 
  //print details 
   Console.WriteLine("name:"+_name); 
   Console.WriteLine("amount:"+_amount); 
}

重构后

public void PrintOwing(double amount) {
    PrintBanner(); 
    //print details 
    PrintDetails();
 } 


private void PrintDetails() { 
    Console.WriteLine("name:" + _name); 
    Console.WriteLine("amount:" + _amount); 
}

2.查询取代临时变量 

重构前

class Price {
  @Autowired
  private Quantity _quantity;
  @Autowired
  private ItemPrice _itemPrice;
 
  public double getPrice() { 
      int basePrice = _quantity * _itemPrice;
      double discountFactor;
      if (basePrice > 5000) { 
          discountFactor = 0.95; 
      } else { 
          discountFactor = 0.98;
      } 
      return basePrice * discountFactor; 
  } 
}

重构后

class Price {
  @Autowired
  private Quantity _quantity;
  @Autowired
  private ItemPrice _itemPrice;


  public double getPrice() {
       return basePrice() * discountFactor(); 
  } 
  private double basePrice() { 
       return _quantity * _itemPrice;
  } 
  private double discountFactor() {
       if (basePrice() > 5000) {
          return 0.95; 
       } else { 
          return 0.98; 
       } 
  }
}

四 重复函数

模板模式

例如人事系统 批量导入中

DataImportProcesser类中的 process方法

模板模式的适用场景特征

 

五 空对象模式 

重构前

class Site {
    Customer _customer;
    Customer getCustomer() { 
      return _customer;
   } 
} 
 
class Customer { 
   public String getName() {...}
   public BillingPlan getPlan() {...} 
   public PaymentHistory getHistory() {...} 
} 
 
class PaymentHistory { 
   public int getWeeksDelinquentInLastYear() { 
     Customer customer = site.getCustomer(); 
     BillingPlan plan; 
     if (customer == null) 
         plan = BillingPlan.basic(); 
     else plan = customer.getPlan(); 
     String customerName; 
     if (customer == null) 
         customerName = "occupant";
     else customerName = customer.getName(); 
      ...
     int weeksDelinquent;
     if (customer == null)
         weeksDelinquent = 0; 
     else weeksDelinquent = customer.getHistory(); 
   } 
}

重构过程

class NullCustomer extends Customer {
     public boolean isNull() { 
       return true; 
     }
 }
 
class Customer { 
     public boolean isNull() { 
       return false;
     } 
     static Customer newNull() {
       return new NullCustomer(); 
     } 
}

class Site { 
     Customer getCustomer() { 
       return (_customer == null) ? Customer.newNull() : _customer; 
    
}
class PaymentHistory {
     Customer customer = site.getCustomer(); 
     BillingPlan plan; 
     if (customer.isNull())
        plan = BillingPlan.basic(); 
     else plan = customer.getPlan(); 
     String customerName; 
     if (customer.isNull()) 
        customerName = "occupant"; 
     else customerName = customer.getName(); 
     int weeksDelinquent; 
     if (customer.isNull()) 
        weeksDelinquent = 0; 
     else weeksDelinquent = customer.getHistory();
     ... 
}

重构后

class NullCustomer extends Customer { 
     public boolean isNull() { 
         return true;
     } 
     public String getName() { 
         return BillingPlan.basic(); 
     }
     public String getPlan() { 
         return "occupant" 
     } 
     public PaymentHistory getHistory() {
         return 0; 
     }
 } 

class Customer { 
     public boolean isNull() { 
         return false;
     } 
     static Customer newNull() { 
         return new NullCustomer(); 
     } 
 } 

class Site { Customer getCustomer() { 
     return (_customer == null) ? Customer.newNull() : _customer; 
} 

class PaymentHistory { 
     public int getWeeksDelinquentInLastYear() { 
         Customer customer = site.getCustomer(); 
         BillingPlan plan = customer.getPlan();
         String customerName = customer.getName(); 
         int weeksDelinquent = customer.getHistory(); 
         ...
     }
 } 
为什么看起来仿佛增加了代码的复杂程度? 

六 过多的注释

当你感觉需要撰写注释,请先尝试重构,试着让所有注释都变得多余!

七 推荐书籍

    《重构——改善既有代码的设计》

       阅读方法

原文地址:https://www.cnblogs.com/wanghongsen/p/9073361.html