IMZRH的日志

努力成为一个有用的人

导航

31天重构指南之二十二:分解方法

Posted on 2009-10-16 13:30  张荣华  阅读(500)  评论(1编辑  收藏  举报

今天要说的重构没有明确的出处,分解方法是我给它起的名字,我相信肯定还有别人做过类似的重构但却叫别一个名字,如果你在看完本文后觉得还有比“分解方法”更好的名字,请通知我。

分解重构是元重构的一种,所做的事情就是不停的分解方法,直到将一个大方法分解为可读性更好的若干个小方法。本文一会要遇到的例子是虚构的,因为现实中AcceptPayment方法不会做这么多的事情。

下面我们通过几次分解将AcceptPayment分解成若干个小方法。

   1: public class CashRegister
   2: {
   3:     public CashRegister()
   4:     {
   5:         Tax = 0.06m;
   6:     }
   7:  
   8:     private decimal Tax { get; set; }
   9:  
  10:     public void AcceptPayment(Customer customer, IEnumerable<Product> products, decimal payment)
  11:     {
  12:         decimal subTotal = 0m;
  13:         foreach (Product product in products)
  14:         {
  15:             subTotal += product.Price;
  16:         }
  17:  
  18:         foreach(Product product in products)
  19:         {
  20:             subTotal -= product.AvailableDiscounts;
  21:         }
  22:  
  23:         decimal grandTotal = subTotal * Tax;
  24:  
  25:         customer.DeductFromAccountBalance(grandTotal);
  26:     }
  27: }
  28:  
  29: public class Customer
  30: {
  31:     public void DeductFromAccountBalance(decimal amount)
  32:     {
  33:         // deduct from balance
  34:     }
  35: }
  36:  
  37: public class Product
  38: {
  39:     public decimal Price { get; set; }
  40:     public decimal AvailableDiscounts { get; set; }
  41: }
 
如你所看到的,AcceptPayment方法中许多代码可以提取到独立的方法中,所以我们应用“提取方法”重构将这些代码提取到独立的方法中,下面是提取后的代码:
   1: public class CashRegister
   2: {
   3:     public CashRegister()
   4:     {
   5:         Tax = 0.06m;
   6:     }
   7:  
   8:     private decimal Tax { get; set; }
   9:     private IEnumerable<Product> Products { get; set; }
  10:  
  11:     public void AcceptPayment(Customer customer, IEnumerable<Product> products, decimal payment)
  12:     {
  13:         decimal subTotal = CalculateSubtotal();
  14:  
  15:         subTotal = SubtractDiscounts(subTotal);
  16:  
  17:         decimal grandTotal = AddTax(subTotal);
  18:  
  19:         SubtractFromCustomerBalance(customer, grandTotal);
  20:     }
  21:  
  22:     private void SubtractFromCustomerBalance(Customer customer, decimal grandTotal)
  23:     {
  24:         customer.DeductFromAccountBalance(grandTotal);
  25:     }
  26:  
  27:     private decimal AddTax(decimal subTotal)
  28:     {
  29:         return subTotal * Tax;
  30:     }
  31:  
  32:     private decimal SubtractDiscounts(decimal subTotal)
  33:     {
  34:         foreach(Product product in Products)
  35:         {
  36:             subTotal -= product.AvailableDiscounts;
  37:         }
  38:         return subTotal;
  39:     }
  40:  
  41:     private decimal CalculateSubtotal()
  42:     {
  43:         decimal subTotal = 0m;
  44:         foreach (Product product in Products)
  45:         {
  46:             subTotal += product.Price;
  47:         }
  48:         return subTotal;
  49:     }
  50: }
  51:  
  52: public class Customer
  53: {
  54:     public void DeductFromAccountBalance(decimal amount)
  55:     {
  56:         // deduct from balance
  57:     }
  58: }
  59:  
  60: public class Product
  61: {
  62:     public decimal Price { get; set; }
  63:     public decimal AvailableDiscounts { get; set; }
  64: }
 

原文链接:http://www.lostechies.com/blogs/sean_chambers/archive/2009/08/22/refactoring-day-22-break-method.aspx

PS:个人认为“分解方法”重构和“提取方法”重构好像是一个重构,只是名字不一样吗?