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

浙公网安备 33010602011771号