概念:本文中的“提取方法对象”是指当你发现一个方法中存在过多的局部变量时,你能够通过使用“提取方法对象”重构来引入一些方法,每一个方法完毕任务的一个步骤,这样能够使得程序变得更具有可读性。

 

正文:例如以下代码所看到的,Order 类中的Calculate方法要完毕非常多功能,在之前我们用“提取方法”来进行重构,如今我们採取“提取方法对象”来完毕重构。

using System.Collections.Generic;

namespace LosTechies.DaysOfRefactoring.ExtractMethodObject.Before
{
    public class OrderLineItem
    {
        public decimal Price { get; private set; }
    }

    public class Order
    {
        private IList<OrderLineItem> OrderLineItems { get; set; }
        private IList<decimal> Discounts { get; set; }
        private decimal Tax { get; set; }

        public decimal Calculate()
        {
            decimal subTotal = 0m;

            // Total up line items
            foreach (OrderLineItem lineItem in OrderLineItems)
            {
                subTotal += lineItem.Price;
            }

            // Subtract Discounts
            foreach (decimal discount in Discounts)
                subTotal -= discount;

            // Calculate Tax
            decimal tax = subTotal * Tax;

            // Calculate GrandTotal
            decimal grandTotal = subTotal + tax;

            return grandTotal;
        }
    }
}

正例如以下代码所看到的。我们引入了OrderCalculator类,该类实现了全部的计算方法,Order类将自身传递给 OrderCalculator类并调用Calculate方法完毕计算过程。

using System.Collections.Generic;

namespace LosTechies.DaysOfRefactoring.ExtractMethodObject.After
{
    public class OrderLineItem
    {
        public decimal Price { get; private set; }
    }

    public class Order
    {
        public IEnumerable<OrderLineItem> OrderLineItems { get; private set; }
        public IEnumerable<decimal> Discounts { get; private set; }
        public decimal Tax { get; private set; }

        public decimal Calculate()
        {
            return new OrderCalculator(this).Calculate();
        }
    }

    public class OrderCalculator
    {
        private decimal SubTotal { get; set; }
        private IEnumerable<OrderLineItem> OrderLineItems { get; set; }
        private IEnumerable<decimal> Discounts { get; set; }
        private decimal Tax { get; set; }

        public OrderCalculator(Order order)
        {
            OrderLineItems = order.OrderLineItems;
            Discounts = order.Discounts;
            Tax = order.Tax;
        }

        public decimal Calculate()
        {
            CalculateSubTotal();

            SubtractDiscounts();

            CalculateTax();

            return SubTotal;
        }

        private void CalculateSubTotal()
        {
            // Total up line items
            foreach (OrderLineItem lineItem in OrderLineItems)
                SubTotal += lineItem.Price;
        }

        private void SubtractDiscounts()
        {
            // Subtract Discounts
            foreach (decimal discount in Discounts)
                SubTotal -= discount;
        }

        private void CalculateTax()
        {
            // Calculate Tax
            SubTotal += SubTotal * Tax;
        }
    }
}

总结:本文的重构方法在有的时候还是比較实用,但这样会造成字段的添加,同一时候也会带来一些维护的不便。它和“提取方法”最大的差别就是一个通过方法返回须要的数据,还有一个则是通过字段来存储方法的结果值,所以在非常大程度上我们都会选择“提取方法”。