软件设计重构秘笈13式-12提取方法对象
概念
本文中的“提取方法对象”是指当你发现一个方法中存在过多的局部变量时,你可以通过使用“提取方法对象”重构来引入一些方法,
每个方法完成任务的一个步骤,这样可以使得程序变得更具有可读性。
意图
提取方法对象解决一个方法中存在过多的局部变量问题
如下代码所示,Order 类中的calculate方法要完成很多功能,在之前我们用“提取方法”来进行重构,现在我们采取“提取方法对象”来完成重构。
案例
public class Order {
private List<OrderLineItem> itemList = new ArrayList<>();
private List<Double> discounts = new ArrayList<>();
private double tax;
public double calculate() {
double subTotal = 0;
if (!itemList.isEmpty()) {
for (OrderLineItem item:itemList) {
subTotal +=item.getPrice();
}
}
if (!discounts.isEmpty()) {
for (Double d:discounts) {
subTotal-=d.doubleValue();
}
}
double t = subTotal * tax;
double grandTotal = subTotal + t;
return grandTotal;
}
}
public class OrderLineItem {
private double price;
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
重构
正如下代码所示,我们引入了OrderCalculator类,该类实现了所有的计算方法,
Order类将自身传递给 OrderCalculator类并调用calculate方法完成计算过程。
public class Order {
private List<OrderLineItem> itemList = new ArrayList<>();
private List<Double> discounts = new ArrayList<>();
private double tax;
public double calculate() {
return new OrderCalculator(this).calculate();
}
public List<OrderLineItem> getItemList() {
return itemList;
}
public void setItemList(List<OrderLineItem> itemList) {
this.itemList = itemList;
}
public List<Double> getDiscounts() {
return discounts;
}
public void setDiscounts(List<Double> discounts) {
this.discounts = discounts;
}
public double getTax() {
return tax;
}
public void setTax(double tax) {
this.tax = tax;
}
}
public class OrderCalculator {
private List<OrderLineItem> itemList = new ArrayList<>();
private List<Double> discounts = new ArrayList<>();
private double tax;
private double subTotal;
public OrderCalculator(Order order) {
itemList = order.getItemList();
discounts = order.getDiscounts();
tax = order.getTax();
}
public double calculate() {
calculateSubTotal();
subtractDiscounts();
calculateTax();
return subTotal;
}
private void calculateSubTotal() {
if (!itemList.isEmpty()) {
for (OrderLineItem item:itemList) {
subTotal +=item.getPrice();
}
}
}
private void subtractDiscounts() {
if (!discounts.isEmpty()) {
for (Double d:discounts) {
subTotal-=d.doubleValue();
}
}
}
private void calculateTax() {
subTotal += subTotal * tax;
}
}
public class OrderLineItem {
private double price;
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
总结
本文的重构方法在有的时候还是比较有用,但这样会造成字段的增加,同时也会带来一些维护的不便,
它和“提取方法”最大的区别就是一个通过方法返回需要的数据,另一个则是通过字段来存储方法的结果值,
所以在很大程度上我们都会选择“提取方法”。