Spiga

一天一个重构方法(1):提取方法

2009-05-05 15:50:24

Extract Method:提炼方法

你有一段代码可以被组织在一起并独立出来,将这段代码放进一个独立方法中,并让方法名称解释该方法的用途。

public class Receipt
{
    private IList<decimal> Discounts { get; set; }
    private IList<decimal> ItemTotals { get; set; }
    public decimal CalculateGrandTotal()
    {
        decimal subTotal = 0m;
        foreach (decimal itemTotal in ItemTotals)
            subTotal += itemTotal;
        if (Discounts.Count > 0)
        {
            foreach (decimal discount in Discounts)
                subTotal -= discount;
        }
        decimal tax = subTotal * 0.065m;
        subTotal += tax;
        return subTotal;
    }
}

你会发现CalculateGrandTotal函数一共做了3件不同的事情:计算总额、折扣和发票税额。开发者为了搞清楚每个功能如何处理而不得不将代码从头看到尾。相比于此,向下面的代码那样将每个任务分解成单独的函数则要节省更多时间,也更具可读性:

public class Receipt
{
	private IList<decimal> Discounts { get; set; }
	private IList<decimal> ItemTotals { get; set; }
	public decimal CalculateGrandTotal()
	{
		decimal subTotal = CalculateSubTotal();
		subTotal = CalculateDiscounts(subTotal);
		subTotal = CalculateTax(subTotal);
		return subTotal;
	}
	private decimal CalculateTax(decimal subTotal)
	{
		decimal tax = subTotal * 0.065m;
		subTotal += tax;
		return subTotal;
	}
	private decimal CalculateDiscounts(decimal subTotal)
	{
		if (Discounts.Count > 0)
		{
			foreach (decimal discount in Discounts)
				subTotal -= discount;
		}
		return subTotal;
	}
	private decimal CalculateSubTotal()
	{
		decimal subTotal = 0m;
		foreach (decimal itemTotal in ItemTotals)
			subTotal += itemTotal;
		return subTotal;
	}
}

Extract Method是最常用的重构手法之一。当有一个过长的方法或者一段需要注释才能让人理解用途的代码,就可以将这段代码放进一个独立的方法中。