软件设计重构秘笈22式-21分解方法
概念
本文中的”分解方法”是指把我们所做的这个功能不停的分解方法,直到将一个大方法分解为名字有意义且可读性更好的若干个小方法。
意图
分解方法为了提高代码的可读性,可维护性
如下代码所示,因为现实中acceptPayment方法不会做这么多的事情。所以我们通过几次分解将 acceptPayment拆分成若干个名字有意义且可读性更好的小方法。
案例
public class CashRegister {
public double tax = 0.06;
public void acceptPayment(Customer customer, List<Product> products, double payment) {
double subTotal = 0;
if (products != null && !products.isEmpty()) {
for (Product product:products) {
subTotal +=product.getPrice();
subTotal -= product.getAvailableDiscounts();
}
}
double grandTotal = subTotal * tax;
customer.deductFromAccountBalance(grandTotal);
}
public double getTax() {
return tax;
}
public void setTax(double tax) {
this.tax = tax;
}
}
public class Product {
private double price;
private double availableDiscounts;
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public double getAvailableDiscounts() {
return availableDiscounts;
}
public void setAvailableDiscounts(double availableDiscounts) {
this.availableDiscounts = availableDiscounts;
}
}
public class Customer {
public void deductFromAccountBalance(double amount) {
// deduct from balance
}
}
重构
重构后的代码如下,我们把acceptPayment的内部逻辑拆分成了calculateSubtotal、subtractDiscounts、addTax、subtractFromCustomerBalance四个功能明确且可读性更好的小方法。
public class CashRegister {
public double tax = 0.06;
List<Product> products;
public void acceptPayment(Customer customer, double payment) {
double subTotal = 0;
subTotal = calculateSubtotal(subTotal);
subTotal = subtractDiscounts(subTotal);
double grandTotal = addTax(subTotal);
subtractFromCustomerBalance(customer,grandTotal);
}
private void subtractFromCustomerBalance(Customer customer, double grandTotal)
{
customer.deductFromAccountBalance(grandTotal);
}
private double addTax(double subTotal)
{
return subTotal * tax;
}
private double subtractDiscounts(double subTotal)
{
if (products != null && !products.isEmpty()) {
for (Product product:products) {
subTotal -= product.getAvailableDiscounts();
}
}
return subTotal;
}
private double calculateSubtotal(double subTotal)
{
if (products != null && !products.isEmpty()) {
for (Product product:products) {
subTotal +=product.getPrice();
}
}
return subTotal;
}
public double getTax() {
return tax;
}
public void setTax(double tax) {
this.tax = tax;
}
}
总结
其实这个重构和我们前面讲的“提取方法”和“提取方法对象”如出一辙,尤其是“提取方法”,所以大家只要知道用这种思想重构就行。