代码重构
试想场景: 我们要写一个逻辑比较复杂的函数, 发现根之前一个函数很类似。 怎么办, 重新写? 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(); ... } } |
为什么看起来仿佛增加了代码的复杂程度? |
六 过多的注释
当你感觉需要撰写注释,请先尝试重构,试着让所有注释都变得多余! |
七 推荐书籍
《重构——改善既有代码的设计》
阅读方法